home *** CD-ROM | disk | FTP | other *** search
- // TSMorph - Amiga Morphing program
- // Copyright (C) © 1993 Topicsave Limited
-
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation; either version 2 of the License, or
- // any later version.
-
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
-
- // You should have received a copy of the GNU General Public License
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- // mpaddock@cix.compulink.co.uk
-
- /* Amiga headers */
- #define INTUI_V36_NAMES_ONLY
- #define INTUITION_IOBSOLETE_H
-
- // Include correct math library
- #ifdef MY68881
- #include <m68881.h>
- extern int rand(void);
- #else
- #ifdef MY68881_6
- #include <math.h>
- #include <m68881.h>
- #else
- #include <math.h>
- #endif
- #endif
-
-
- // prevent inclusion of another math library
- #define LIBRARIES_MATHFFP_H
-
- // other headers, define some non 2.02 header stuff
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <intuition/gadgetclass.h>
- #ifndef PGA_NewLook
- #define PGA_NewLook (PGA_Dummy + 0x000A)
- #endif
- #include <intuition/imageclass.h>
- #include <intuition/icclass.h>
- #include <devices/input.h>
- #include <workbench/workbench.h>
- #include <workbench/startup.h>
- #include <libraries/gadtools.h>
- #ifndef GTMN_FullMenu
- #define GTMN_FullMenu GT_TagBase+62
- #endif
- #include <libraries/asl.h>
-
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/layers_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/input_protos.h>
- #include <clib/gadtools_protos.h>
- #include <clib/asl_protos.h>
- #include <clib/utility_protos.h>
- #include <clib/alib_protos.h>
-
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/layers_pragmas.h>
- #include <pragmas/graphics_pragmas.h>
- #include <pragmas/intuition_pragmas.h>
- #include <pragmas/input_pragmas.h>
- #include <pragmas/gadtools_pragmas.h>
- #include <pragmas/asl_pragmas.h>
- #include <pragmas/utility_pragmas.h>
-
- #include <proto/diskfont.h>
- #include <proto/icon.h>
-
- #include <devices/timer.h>
-
- #include <clib/timer_protos.h>
- #include <pragmas/timer_pragmas.h>
-
- #include <clib/alib_protos.h>
-
- #include <rexx/errors.h>
- #include <pragmas/rexxsyslib_pragmas.h>
- #include <clib/rexxsyslib_protos.h>
-
- #include <libraries/amigaguide.h>
- #include <clib/amigaguide_protos.h>
- #include <pragmas/amigaguide_pragmas.h>
-
- #include <libraries/reqtools.h>
- #include <clib/reqtools_protos.h>
- #include <pragmas/reqtools.h>
-
- #include <opal/opallib.h>
-
- #include <libraries/dctv.h>
- #include <clib/dctv_protos.h>
- #include <pragmas/dctv_pragmas.h>
-
- #include <libraries/nofrag.h>
- #include <clib/nofrag_protos.h>
- #ifdef LIBRARIES_NOFRAG_H
- #undef LIBRARIES_NOFRAG_H
- #endif
- #include <pragmas/nofrag_pragmas.h>
- #ifndef LIBRARIES_NOFRAG_H
- #define LIBRARIES_NOFRAG_H 1
- #endif
-
- #include <stddef.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
-
- /* Below is not in the 2.02 version of clib/utility_protos.h
- pragmas/utility_pragmas.h */
- #if INCLUDE_VERSION < 37
- LONG Stricmp(UBYTE *string1,UBYTE *string2);
- #pragma libcall UtilityBase Stricmp A2 9802
- #endif
-
- /* EGS Stuff */
- #include <egs/clib/egs_protos.h>
- #include <egs/pragmas/egs_pragmas.h>
-
- #include <egs/clib/egsintui_protos.h>
- #include <egs/pragmas/egsintui_pragmas.h>
-
- #include <egs/clib/egsgfx_protos.h>
- #include <egs/pragmas/egsgfx_pragmas.h>
-
- #include <egs/egsintui.h>
-
- extern struct Library *EGSIntuiBase = NULL;
- extern struct Library *EGSGfxBase = NULL;
- extern struct Library *EGSBase = NULL;
-
- // IFF header
- #include "iffp/ILBMapp.h"
-
- // Progress requester
- #include "progress.h"
-
- // JPEG load stuff
- #include "JPEG_LS/jinclude.h"
-
- // Help nodes
- STRPTR context[] = {
- "",
- "Main",
- "Err-IFFBMHD",
- "Err-IFFRaster",
- "Err-IFFBODY",
- "Err-IFFCLIP",
- "Err-IFFILBM",
- "Err-IFFFileS",
- "Err-IFFTop",
- "Err-IFFMemory",
- "Req-Progress",
- "Err-LibraryR",
- "Err-Saving",
- "Err-AllocVec",
- "Err-OpenPoints",
- "Err-Progress",
- "Err-AllocPlanes",
- "Err-24",
- "Err-Load",
- "Err-AllocIFF",
- "Err-AllocILBM",
- "Err-FileFormat",
- "Err-SizeMatch",
- "Err-Range",
- "Err-MemPointsR",
- "Err-CloseFile",
- "Err-3Points",
- "Err-OpenFile",
- "Err-ARexx",
- "Req-Really_quit",
- "Err-OldFormat",
- "Err-OpalVision",
- "Err-NoOpal",
- };
-
- #define H_Help 10
- #define H_Library 11
- #define H_ESave 12
- #define H_AllocVec 13
- #define H_OpenPoints 14
- #define H_Progress 15
- #define H_AllocPlanes 16
- #define H_24 17
- #define H_Load 18
- #define H_AllocIFF 19
- #define H_AllocILBM 20
- #define H_FileFormat 21
- #define H_SizeMatch 22
- #define H_Range 23
- #define H_MemPointsR 24
- #define H_CloseFile 25
- #define H_3Points 26
- #define H_Open 27
- #define H_ARexx 28
- #define H_Really 29
- #define HE_OldFormat 30
- #define HE_OpalVision 31
- #define HE_NoOpal 32
-
- // Disable Ctrl-C checking
- int CXBRK(void) { return(0); }
- int chkabort(void) { return(0); }
- int __regargs __chkabort(void) { return(0); }
-
- // Libraries
- extern struct ExecBase *SysBase;
- extern struct DosLibrary *DOSBase;
- struct IntuitionBase *IntuitionBase;
- struct Library *GfxBase, *LayersBase, *IFFParseBase;
- struct Library *GadToolsBase, *AslBase, *UtilityBase;
- struct Library *RexxSysBase;
- struct Library *AmigaGuideBase;
- struct Library *TimerBase=NULL;
- struct Library *ReqToolsBase;
- struct Library *DCTVBase;
- struct NoFragBase *NoFragBase = NULL;
-
- struct OpalBase *OpalBase = NULL;
-
- extern struct List InfoList={0}; // List of messages
-
- // Help stuff
- extern AMIGAGUIDECONTEXT handle = {NULL};
- extern struct NewAmigaGuide nag = {NULL};
- extern ULONG ASig = 0;
-
- /* Version string for CLI version */
- #ifdef MY68881
- char *Version = "$VER: TSMorph-render_881 3.2 (12.3.95)";
- #else
- #ifdef _M68040
- char *Version = "$VER: TSMorph-render_040 3.2 (12.3.95)";
- #else
- #ifdef MY68881_6
- char *Version = "$VER: TSMorph-render_881 3.2 (12.3.95)";
- #else
- char *Version = "$VER: TSMorph-render 3.2 (12.3.95)";
- #endif
- #endif
- #endif
-
- BOOL Pic1_Open = FALSE; // 1st image open OK
- BOOL Pic2_Open = FALSE; // 2nd image open OK
-
- struct MsgPort *WMsgPortp; // Message port for Picture Windows
-
- // Properties for IFF read
- LONG props[] = { ID_ILBM, ID_BMHD,
- ID_ILBM, ID_CAMG,
- ID_ILBM, ID_CMAP,
- TAG_DONE };
- LONG stops[] = { ID_ILBM, ID_BODY,
- TAG_DONE };
- LONG nowt[] = { TAG_DONE };
-
- struct EI_NewWindow EGS_NewWindow = {0}; // EGS New window
- struct EI_Window *EGS_Win=NULL; // EGS Window
- struct E_EBitMap *EGS_BitMap=NULL;
-
- // Protos
- BOOL SaveFile(void);
- BOOL Load24bit(char *filename,struct Picture *pic,BOOL GUI);
- void Close24bit(struct Picture *pic);
- void DeleteAllPoints(void);
- static void __regargs FindPoint(struct MyPoint *RetPoint,BOOL Everything);
- BOOL MyOpen(char *filename,BOOL JustPoints);
- static UWORD __regargs intersect(struct MyPoint *Pointa,struct MyPoint *Pointb);
- static void __regargs CalcDiffs(struct MyPoint *a,struct MyPoint *bb,double *ab1,double *ab2,double *ab);
- static void __regargs Triangle(struct MyPoint *p,struct MyPoint *a,struct MyPoint *bb,struct MyPoint *c);
- static void __regargs Triangle_I(struct MyPoint *p,struct MyPoint *a,struct MyPoint *bb,struct MyPoint *c);
- extern void MyArgArrayInit(int argc,char **argv);
- extern void MyArgArrayDone(void);
- extern UBYTE *MyArgString(UBYTE *arg2,UBYTE *arg3,BOOL reopen);
- extern LONG MyArgInt(UBYTE *arg2, long arg3,BOOL reopen);
- extern BOOL MyFindToolType(UBYTE *arg2,BOOL reopen);
- void OpenNewArgs(UBYTE *filename);
- void help(ULONG hnum);
- BOOL LoadFrames(BOOL points,BOOL image1,BOOL image2);
- void CopyEGS(int line, UBYTE **er,UBYTE **eg,UBYTE **eb);
- int cmpX(struct MyPoint **A,struct MyPoint **B);
- int cmpY(struct MyPoint **A,struct MyPoint **B);
- int cmpDiff(struct MyPoint **A,struct MyPoint **B);
- BOOL GenerateTriangles(void);
- void FreeTriangles(void);
- int *IntVect(int ncols);
- void MyFreeVecti(int *vectptr);
- int **IntMatrix(int nrows,int ncols);
- void FreeMatrixi(int **matptr);
- double **DoubleMatrix(int nrows,int ncols);
- void FreeMatrixd(double **matptr);
- BOOL AddTri(int aa,int bb,int cc);
- void AddMessage(UBYTE *message);
-
- // Args.c
- void argArrayDone( void );
- char **argArrayInit( LONG argc, char **argv );
-
- // RenderSub.c
- void DisableWindow(void);
- void EnableWindow(void);
- APTR MyAllocVec(ULONG size,ULONG requirements);
- void MyFreeVec(APTR memptr);
- APTR MyAllocMem(ULONG size,ULONG requirements);
- void MyFreeMem(APTR memptr,ULONG size);
- APTR Mymalloc(ULONG size);
- APTR Mystrdup(UBYTE *str);
- void Error(char *ErrorMessage, char *Gadget,char *extra,ULONG hnum);
- LONG SendRxMsg(char *msgtxt,BOOL IgnoreError);
-
- // some work buffers
- extern char buffer[256]="";
- extern char buffer1[512]="";
-
- // Image structure
- struct Picture {
- struct ILBMInfo *ilbm; // For IFF read
- UBYTE *red; // Read chunky pixels Must be RGB for Opal OVtoRGB
- UBYTE *green; // Green
- UBYTE *blue; // Blue
- UBYTE filename[256]; // filename
- struct OpalScreen *OScrn; // OpalScreen
- BOOL rgbonelot; // Is red,green,blue one AllocVec
- };
-
- struct Picture Pic1={0},Pic2={0};// 1st and 2nd image
-
- extern UBYTE *plane0=NULL; // Planes for temporary bit maps
- extern UBYTE *plane1=NULL;
- extern UBYTE *plane2=NULL;
- extern UBYTE *plane3=NULL;
- extern UBYTE *plane4=NULL;
- extern UBYTE *plane5=NULL;
- extern UBYTE *plane6=NULL;
- extern UBYTE *plane7=NULL;
-
- // nofrag.library stuff
- extern struct MemoryChain *Chain = NULL;
- #define MAXMEM 1000
-
- // Point structure
- struct MyPoint {
- struct MinNode MyNode; // linked into list
- WORD x,y; // Coordinates in 1st image
- WORD x1,y1; // 2nd image
- WORD Cx,Cy; // Current image
- LONG Cdiff; // seperation between two points (squared)
- WORD xdiff; // x difference
- WORD ydiff; // y difference
- double xd,yd; // double coords for AntiAlias
- double x1d,y1d;// 2nd image
- BOOL Used; // Is it being used?
- struct List TList; // List of triangles;
- };
-
- struct Triangle {
- struct MinNode TNode; // Linked into list
- struct MyPoint *Point1;
- struct MyPoint *Point2;
- };
-
- // 24 bitplane bitmap
- struct MyBitMap {
- struct BitMap BitMap;
- PLANEPTR xplanes[16];
- };
-
- // List of points
- struct List PointList;
-
- // Size of image
- extern USHORT width=0, height=0, pwidth=0, pheight=0, pmode=0;
-
- char AnimName[256]=""; // Buffer for file name to save
-
- char *Loadscript; // ARexx load script
-
- extern WORD x=0,y=0; // Current coords
-
- struct MyPoint **Points = NULL; // Pointer to points
- struct MyPoint **PointsAlloc = NULL; // The actual allocated pointer
- struct MyPoint **PointsX = NULL; // Pointer to points horizontal
- struct MyPoint **PointsY = NULL; // Pointer to points vertical
-
- WORD Depth; // Number of points to check each time
-
- UWORD Mode; // Mode = 0 use 3 closest if no others, choose 1st 3
- // Mode = 1 leave points stationary, choose 1st 3
- // Mode = 2 choose 3 closet, always use
- // Mode = 3 leave points stationary, choose 3 closest
- // Mode = 4 Binary search ,5,6,7 as above
- // Mode = 8 Delaunay Triangle algorithm
- // Mode = 16 Only calculate points once
-
-
- // SET/UNSET
- #define MODE_STAT 1 // Stationary if no triangle/Use 3 points anyway
- #define MODE_CLOSEST 2 // Choose 3 closest/Choose 1st 3 found
- #define MODE_SEARCH 4 // Binary Search/Look at all points
- #define MODE_DELAU 8 // Delaunay Triangle/Normal mode (sets DEPTH to 0)
- #define MODE_ONCE 16 // Only calculate once
-
- LONG PointCount = 0; // Number of points
-
- struct MyPoint BigPoint; // Point far away
-
- char MyFileName[257];
-
- // Settings stuff
- char **ArgArray;
- char **ArgArraySettings;
-
- // OpalVision screen
- extern struct OpalScreen *OScrn = NULL;
-
- extern char *OVFormat=NULL; // Format of OpalVision save JPG or IFF (or anything) default
- BOOL AntiAlias; // AntiAlias points
-
- // Table of parameters
- extern struct {
- LONG xf; // Current frame
- LONG xFrames; // Number of frames
- LONG xSingle; // Warp or Morph
- LONG xmove; // Movement 1 to 2
- LONG xr; // red of image 1
- LONG xg; // green
- LONG xb; // blue
- LONG xr2; // red of image 2
- LONG xg2; // green
- LONG xb2; // blue
- LONG xDo; // Produce this image
- LONG xrplus; // Add red
- LONG xgplus; // green
- LONG xbplus; // blue
- LONG xrminus; // subtract red
- LONG xgminus; // subtract green
- LONG xbminus; // subtract blue
- LONG xDX; // X skip
- LONG xDY; // Y skip
- LONG xStart; // Start Frame number
- LONG FILLER[32]; // Filler for future expansion
- } Arexx = {0};
-
- #define f Arexx.xf
- #define Frames Arexx.xFrames
- #define Single Arexx.xSingle
- #define move Arexx.xmove
- #define r Arexx.xr
- #define g Arexx.xg
- #define b Arexx.xb
- #define r2 Arexx.xr2
- #define g2 Arexx.xg2
- #define b2 Arexx.xb2
- #define Do Arexx.xDo
- #define rplus Arexx.xrplus
- #define gplus Arexx.xgplus
- #define bplus Arexx.xbplus
- #define rminus Arexx.xrminus
- #define gminus Arexx.xgminus
- #define bminus Arexx.xbminus
- #define DX Arexx.xDX
- #define DY Arexx.xDY
- #define Start Arexx.xStart
-
- // Display help if available
- void
- help(ULONG hnum) {
- if (handle) {
- SetAmigaGuideContext(handle,hnum,NULL);
- SendAmigaGuideContext(handle,NULL);
- }
- }
-
- extern char FileName[256]=""; // File name buffer
- extern long OVQuality=0; // OpalVision JPG quality
- extern BOOL OVFast=FALSE; // OpalVision fast format IFF
- extern BOOL OVThumb=FALSE; // OpalVision Thumbail
- extern BOOL HAM6=FALSE;
- extern BOOL HAM8=FALSE;
- extern BOOL BW16=FALSE;
- extern BOOL BW256=FALSE;
- extern BOOL DCTV3 = FALSE;
- extern BOOL DCTV4 = FALSE;
- extern UBYTE *arrayr=NULL, // Pointers to red,green and blue
- *arrayg=NULL,
- *arrayb=NULL;
- extern BOOL PPM=FALSE; // PPM save ?
- extern BOOL EGS=FALSE; // EGS Preview
- extern UBYTE *p[3] = {NULL,NULL,NULL};// chunky pointers - order for OpalVision
- #define RED p[0]
- #define BLUE p[2]
- #define GREEN p[1]
- extern UWORD swidth=0; // scaled width (in full words)
- extern struct RastPort RP={0}, // Work Rast Ports
- TRP={0};
- extern struct MyBitMap MyBitMap={0}; // Real bit map
- extern PLANEPTR Planes[24] = {NULL}; // Bit planes
- extern BOOL CreateIcons=FALSE;// Create Icons on pictures?
-
- extern char *Postscript=NULL;// ARexx postscript
- BOOL Integer = FALSE;
-
- /* Main program */
- int
- main(int argc,char **argv) {
- BOOL OkFlag = TRUE; // Is it working ?
- char *e = NULL; // error message
- struct MyPoint MyPoint; // Points to work with
- struct MyPoint *MyPointp;
- BOOL Opened; // has file been opened
- struct WBStartup *argmsg; // Workbench stuff
- struct WBArg *wb_arg;
- char *e1; // The rest of the error message
- struct Window *oldWindowPtr; // Redirect the system requesters
- struct Process *process;
- char *filename; // file name
- ULONG offset, // 2d to 1d array offsets
- offset1;
- char *Prescript; // Rexx script names
- UWORD myx, // indexes for skipping
- myy;
- UBYTE xr, // more skipping stuff
- xg,
- xb;
- struct AmigaGuideMsg *agm; // help stuff
- struct timeval time1, // To display time per image
- time2;
- struct timerequest tr;
- BOOL t2 = FALSE; // Set when the times calculated
- char tbuffer[30];// buffer for time message
- ULONG hnum = 0; // Help number for error
- BOOL Alloced=FALSE; // Allocated memory?
- char *Tstr; // Temp string for parameter
- UWORD xbig;
- double xsmall; // Int and rest of coords
- UWORD ybig;
- double ysmall; // y coords
- WORD right,down; // move right and down?
- UWORD xbig1;
- double xsmall1; // Int and rest of coords
- UWORD ybig1;
- double ysmall1; // y coords
- WORD right1,down1;// move right and down?
- double a,bb,c,d,a1,b1,c1,d1; // AntiAlias stuff
- UBYTE *er,*eg,*eb;// EGS pointers
-
- // Set up BigPoint
- BigPoint.Cdiff = 0x7FFFFFFF;
- // Initialise points list
- NewList(&PointList);
- // Try and open reqtools.library and dctv.library and nofrag.library
- ReqToolsBase = OpenLibrary("reqtools.library",38);
- DCTVBase = OpenLibrary("dctv.library",3);
- if (NoFragBase = (struct NoFragBase *) OpenLibrary("nofrag.library",2L)) {
- if (!(Chain = GetMemoryChain(MAXMEM+20))) {
- CloseLibrary((struct Library *)NoFragBase);
- NoFragBase = NULL;
- }
- }
- // Set up amigaguide (if available)
- if (AmigaGuideBase = OpenLibrary ("amigaguide.library", 33L)) {
- nag.nag_BaseName = "TSMorph";
- nag.nag_Name = "TSMorph.guide";
- nag.nag_ClientPort = "TSMorph-render_HELP";
- nag.nag_Context = context;
- if (handle = OpenAmigaGuideAsync (&nag, NULL)) {
- ASig = AmigaGuideSignal(handle);
- }
- }
- // Try and open the timer
- if (!OpenDevice(TIMERNAME,UNIT_MICROHZ,(struct IORequest *) &tr, 0L)) {
- TimerBase = (struct Library *)tr.tr_node.io_Device;
- }
- // Try and open OpalVision library
- OpalBase = (struct OpalBase *)OpenLibrary("opal.library",0L);
- // Open all the libraries
- if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37L)) {
- if (RexxSysBase = OpenLibrary("rexxsyslib.library",0)) {
- if (IFFParseBase = OpenLibrary("iffparse.library",37L)) {
- if (GfxBase = OpenLibrary("graphics.library",37L)) {
- if (LayersBase = OpenLibrary("layers.library",37L)) {
- if (GadToolsBase = OpenLibrary("gadtools.library",37L)) {
- if (AslBase = OpenLibrary("asl.library",37L)) {
- if (UtilityBase = OpenLibrary("utility.library",37)) {
- if (IconBase = OpenLibrary("icon.library",37L)) {
- if (DiskfontBase = OpenLibrary("diskfont.library",36)) {
- // Read and process the parameters
- MyArgArrayInit(argc,argv);
- if (MatchToolValue(MyArgString("EGS","NO",FALSE),"YES")) {
- if ((EGSBase = OpenLibrary("egs.library",0)) &&
- (EGSGfxBase = OpenLibrary("egsgfx.library", 0)) &&
- (EGSIntuiBase = OpenLibrary("egsintui.library", 0))) {
- EGS = TRUE;
- }
- }
- if (MatchToolValue(MyArgString("REQTOOLS","YES",FALSE),"NO")) {
- if (ReqToolsBase) {
- CloseLibrary(ReqToolsBase);
- ReqToolsBase = NULL;
- }
- }
- PubScreenName = MyArgString("PUBSCREENR",NULL,FALSE);
- // Open the progress window
- if ((!SetupScreen()) && (!OpenProgressWindow())) {
- // redirect requesters
- process = (struct Process *)FindTask(NULL);
- oldWindowPtr = process->pr_WindowPtr;
- process->pr_WindowPtr = ProgressWnd;
- // Open the project file (CLI or WB)
- DisableWindow();
- AddMessage("Opening points file");
- if (argc) {
- if (filename = ArgString(ArgArray,"FILES",NULL)) {
- Opened = MyOpen(filename,FALSE);
- }
- else {
- Opened = MyOpen(NULL,FALSE);
- }
- }
- else {
- argmsg = (struct WBStartup *)argv;
- if (argmsg->sm_NumArgs > 1) {
- wb_arg = argmsg->sm_ArgList;
- wb_arg++;
- if (wb_arg->wa_Lock) {
- NameFromLock(wb_arg->wa_Lock,buffer,256);
- }
- if (AddPart(buffer,wb_arg->wa_Name,256)) {
- Opened = MyOpen(buffer,FALSE);
- }
- }
- else {
- Opened = MyOpen(NULL,FALSE);
- }
- }
- if (Opened) {
- // Get a few parameters
- Tstr = MyArgString("SAVEFORMAT","ILBM24",FALSE);
- if (OpalBase) {
- if (MatchToolValue(Tstr,"OPAL24") || MatchToolValue(Tstr,"OPAL24T") ||
- MatchToolValue(Tstr,"OPAL24F") || MatchToolValue(Tstr,"OPAL24FT")) {
- OVFormat = "IFF";
- }
- else {
- if (MatchToolValue(Tstr,"JPEG") || MatchToolValue(Tstr,"JPEGT")) {
- OVFormat = "JPG";
- }
- else {
- OVFormat = NULL;
- }
- }
- }
- else {
- OVFormat = NULL;
- }
- PPM = MatchToolValue(Tstr,"PPM");
- HAM6 = MatchToolValue(Tstr,"HAM6");
- HAM8 = MatchToolValue(Tstr,"HAM8");
- BW16 = MatchToolValue(Tstr,"BW16");
- BW256 = MatchToolValue(Tstr,"BW256");
- if (DCTVBase) {
- DCTV3 = MatchToolValue(Tstr,"DCTV3");
- DCTV4 = MatchToolValue(Tstr,"DCTV4");
- }
- OVQuality = MyArgInt("QUALITY",75,FALSE);
- if (MatchToolValue(Tstr,"OPAL24T") || MatchToolValue(Tstr,"JPEGT")) {
- OVThumb = TRUE;
- }
- else {
- OVThumb = FALSE;
- }
- if (MatchToolValue(Tstr,"OPAL24F") || MatchToolValue(Tstr,"OPAL24FT")) {
- OVFast = TRUE;
- }
- else {
- OVFast = FALSE;
- }
- Prescript = MyArgString("PRESCRIPT","Rexx/Prescript",FALSE);
- Postscript = MyArgString("POSTSCRIPT","Rexx/Postscript",FALSE);
- Loadscript = MyArgString("LOADSCRIPT","Rexx/Loadscript",FALSE);
- DX = MyArgInt("DX",0,FALSE);
- DY = MyArgInt("DY",0,FALSE);
- // Depth = min(MyArgInt("DEPTH",2,FALSE),20); Set in Open()
- // Mode = MyArgInt("MODE",0,FALSE);
- CreateIcons = MatchToolValue(MyArgString("CREATEICONSR","NO",FALSE),"YES");
- AntiAlias = MatchToolValue(MyArgString("ANTIALIAS","NO",FALSE),"YES");
- Integer = MatchToolValue(MyArgString("INTEGER","NO",FALSE),"YES");
- if (Integer) {
- AntiAlias = FALSE;
- }
- // File has been opened, cache width in full words
- swidth = (((width+15)>>4)<<4);
- AddMessage("Allocating work memory");
- // Allocate chunky and ILBM bit maps
- if ((RED = AllocVec((swidth*height),MEMF_CLEAR)) &&
- (GREEN = AllocVec((swidth*height),MEMF_CLEAR)) &&
- (BLUE = AllocVec((swidth*height),MEMF_CLEAR)) &&
- ((OpalBase && OVFormat && !PPM && (OScrn = CreateScreen24(0,width,height))) ||
- PPM ||
- (!OVFormat && !PPM &&
- (Planes[0] = AllocRaster(width,height)) &&
- (Planes[1] = AllocRaster(width,height)) &&
- (Planes[2] = AllocRaster(width,height)) &&
- (DCTV3 ||
- ((Planes[3] = AllocRaster(width,height)) &&
- (DCTV4 || BW16 ||
- ((Planes[4] = AllocRaster(width,height)) &&
- (Planes[5] = AllocRaster(width,height)) &&
- (HAM6 ||
- ((Planes[6] = AllocRaster(width,height)) &&
- (Planes[7] = AllocRaster(width,height)) &&
- (HAM8 || BW256 ||
- ((Planes[8] = AllocRaster(width,height)) &&
- (Planes[9] = AllocRaster(width,height)) &&
- (Planes[10] = AllocRaster(width,height)) &&
- (Planes[11] = AllocRaster(width,height)) &&
- (Planes[12] = AllocRaster(width,height)) &&
- (Planes[13] = AllocRaster(width,height)) &&
- (Planes[14] = AllocRaster(width,height)) &&
- (Planes[15] = AllocRaster(width,height)) &&
- (Planes[16] = AllocRaster(width,height)) &&
- (Planes[17] = AllocRaster(width,height)) &&
- (Planes[18] = AllocRaster(width,height)) &&
- (Planes[19] = AllocRaster(width,height)) &&
- (Planes[20] = AllocRaster(width,height)) &&
- (Planes[21] = AllocRaster(width,height)) &&
- (Planes[22] = AllocRaster(width,height)) &&
- (Planes[23] = AllocRaster(width,height))))))))))))) { // Looks like LISP!!!!
- Alloced = TRUE;
- // Update the progress
- EnableWindow();
- GT_SetGadgetAttrs(ProgressGadgets[GDX_Frame],ProgressWnd,NULL,
- GTSL_Min,1,
- GTSL_Max,Frames,TAG_END);
- GT_SetGadgetAttrs(ProgressGadgets[GDX_Line],ProgressWnd,NULL,
- GTSL_Min,0,
- GTSL_Max,height-1,TAG_END);
- // Pass to ARexx for processing
- if (strcmp(Prescript,"OFF")) {
- AddMessage("Prescript for frame 0");
- f = 0;
- Do = 0;
- strcpy(buffer,Prescript);
- strcat(buffer," %ld");
- sprintf(buffer1,buffer,&Arexx);
- OkFlag = !SendRxMsg(buffer1,FALSE);
- if (!OkFlag) {
- e = (char *)-1;
- }
- if (Do && OkFlag) {
- OkFlag = LoadFrames(FALSE,TRUE,FALSE);
- if (!OkFlag) {
- e = (char *)-1;
- }
- else {
- AddMessage("Saving frame 0");
- memcpy(RED,Pic1.red,swidth*height);
- memcpy(GREEN,Pic1.green,swidth*height);
- memcpy(BLUE,Pic1.blue,swidth*height);
- OkFlag = SaveFile();
- if (!OkFlag) {
- e = (char *)-1;
- }
- }
- }
- }
- if ((Mode & MODE_ONCE) && OkFlag) {
- AddMessage("Precalculating points");
- Points = PointsAlloc;
- for (MyPointp = (struct MyPoint *)PointList.lh_Head;
- MyPointp->MyNode.mln_Succ;
- MyPointp = (struct MyPoint *)MyPointp->MyNode.mln_Succ) {
- MyPointp->Cx = (MyPointp->x1+MyPointp->x)>>1;
- MyPointp->Cy = (MyPointp->y1+MyPointp->y)>>1;
- }
- for (y=0;
- ((y<height) && OkFlag);
- y++) {
- // Loop thru columns
- for (x=0;
- x < width;
- x++) {
- // Determine coordinates on end image(s)
- FindPoint(&MyPoint,FALSE);
- Points += (Depth+4);
- if (DX) {
- x++;
- for (myx = 0;
- (myx < DX) && (x < width);
- x++,myx++) {
- Points += (Depth+4);
- }
- x--;
- }
- }
- // end of line, check 'Stop' and 'Help'
- OkFlag = HandleProgressIDCMP();
- if (handle) {
- while (agm = GetAmigaGuideMsg(handle)) {
- ReplyAmigaGuideMsg(agm);
- }
- }
- if (DY) {
- y++;
- for (myy = 0;
- (myy < DY) && (y<height);
- y++, myy++) {
- Points += ((Depth+4)*width);
- }
- y--;
- }
- }
- // not ok - already displayed an error
- if (!OkFlag) {
- e = (char *)-1;
- }
- else {
- if (Mode & MODE_DELAU) {
- AddMessage("Calculating triangles");
- OkFlag = GenerateTriangles();
- if (!OkFlag) {
- Error("Out of memory for points","Quit",NULL,H_MemPointsR);
- }
- }
- }
- }
- // Determine start time
- if (TimerBase) {
- GetSysTime(&time1);
- }
- // Loop thru frames
- for (f=1;
- (f < (Frames+1)) && OkFlag; // no of Frames
- f++) {
- // Update progress
- AddMessage("Prescript processing");
- GT_SetGadgetAttrs(ProgressGadgets[GDX_Frame],ProgressWnd,NULL,
- GTSL_Level,f,TAG_END);
- // calculate default image parameters
- rplus = gplus = bplus = rminus = gminus = bminus = 0;
- if ((Single == 1) || (Single == 3)) {
- move = ((Frames-f) << 10)/Frames;
- r = g = b = 1024;
- r2 = g2 = b2 = 0;
- Do = 1;
- }
- else {
- r = g = b = move = ((Frames-f+1) << 10)/(Frames + 1);
- r2 = g2 = b2 = (1024 - r);
- Do = 1;
- }
- // Pass to ARexx for processing
- if (strcmp(Prescript,"OFF")) {
- strcpy(buffer,Prescript);
- strcat(buffer," %ld");
- sprintf(buffer1,buffer,&Arexx);
- OkFlag = !SendRxMsg(buffer1,FALSE);
- if (!OkFlag) {
- e = (char *)-1;
- }
- }
- if (OkFlag && Do && ((!Pic1_Open) || (Single == 2) || (Single == 3))) {
- if (Pic2_Open) {
- Close24bit(&Pic2);
- Pic2_Open = FALSE;
- }
- if (Pic1_Open) {
- Close24bit(&Pic1);
- Pic1_Open = FALSE;
- }
- OkFlag = LoadFrames(TRUE,TRUE,TRUE);
- if (!OkFlag) {
- e = (char *)-1;
- }
- }
- else { // Version 2.4 - Open frame 2 if not yet open
- if (OkFlag && Do && !Pic2_Open && (Single == 0)) {
- OkFlag = LoadFrames(FALSE,FALSE,TRUE);
- }
- }
- if ((PointCount < 3) && OkFlag) {
- Error("Must have at least 3 points","Quit",NULL,H_3Points);
- OkFlag = FALSE;
- }
- if (Do && OkFlag) {
- // If we have calculated time per image the display it, update other gadgets
- if (t2) {
- sprintf(tbuffer,"%ld.%02ld Seconds for last image",time2.tv_secs,time2.tv_micro/10000);
- AddMessage(tbuffer);
- }
- else {
- AddMessage("Rendering image");
- }
- if (TimerBase) {
- GetSysTime(&time1);
- }
- // We want to do this image so calculate coordinates in this image
- if ((Single == 1) || (Single == 3)) {
- for (MyPointp = (struct MyPoint *)PointList.lh_Head;
- MyPointp->MyNode.mln_Succ;
- MyPointp = (struct MyPoint *)MyPointp->MyNode.mln_Succ) {
- MyPointp->Cx = (MyPointp->x1*(1024-move)+MyPointp->x*move)>>10;
- MyPointp->Cy = (MyPointp->y1*(1024-move)+MyPointp->y*move)>>10;
- }
- }
- else {
- for (MyPointp = (struct MyPoint *)PointList.lh_Head;
- MyPointp->MyNode.mln_Succ;
- MyPointp = (struct MyPoint *)MyPointp->MyNode.mln_Succ) {
- MyPointp->Cx = (MyPointp->x1*(1024-move)+MyPointp->x*move)>>10;
- MyPointp->Cy = (MyPointp->y1*(1024-move)+MyPointp->y*move)>>10;
- }
- }
- if (Mode & MODE_SEARCH) {
- AddMessage("Sorting points");
- qsort((char *)PointsX,PointCount,sizeof(struct MyPoint *),cmpX);
- qsort((char *)PointsY,PointCount,sizeof(struct MyPoint *),cmpY);
- }
- if ((Mode & MODE_DELAU) && (!MODE_ONCE)) {
- AddMessage("Calculating triangles");
- OkFlag = GenerateTriangles();
- if (!OkFlag) {
- Error("Out of memory for points","Quit",NULL,H_MemPointsR);
- }
- }
- // Initialise chunky pointers
- er = arrayr=RED;
- eg = arrayg=GREEN;
- eb = arrayb=BLUE;
- Points = PointsAlloc;
- // loop thru lines
- for (y=0;
- (y<height) && OkFlag;
- y++) {
- // Update progress
- GT_SetGadgetAttrs(ProgressGadgets[GDX_Line],ProgressWnd,NULL,
- GTSL_Level,(ULONG)y,TAG_END);
- // Loop thru columns
- for (x=0;
- x < width;
- x++) {
- // Determine coordinates on end image(s)
- FindPoint(&MyPoint,TRUE);
- if (Mode & MODE_ONCE) {
- Points += (Depth+4);
- }
- if (AntiAlias) {
- // Horrible AntiAlias stuff
- xbig = floor(MyPoint.xd + 0.5);
- xsmall = MyPoint.xd - (double)xbig;
- if (xsmall > 0) {
- right = 1;
- }
- else {
- xsmall = -xsmall;
- right = -1;
- }
- ybig = floor(MyPoint.yd + 0.5);
- ysmall = MyPoint.yd - (double)ybig;
- if (ysmall > 0) {
- down = swidth;
- }
- else {
- ysmall = -ysmall;
- down = -swidth;
- }
- offset = ybig*swidth+xbig;
- a = 1.0 + (xsmall * ysmall) - xsmall - ysmall;
- bb = xsmall * (1.0 - ysmall);
- c = ysmall * (1.0 - xsmall);
- d = xsmall * ysmall;
- if ((Single != 1) && (Single != 3)) {
- xbig1 = floor(MyPoint.x1d + 0.5);
- xsmall1 = MyPoint.x1d - (double)xbig1;
- if (xsmall1 > 0) {
- right1 = 1;
- }
- else {
- xsmall1 = -xsmall1;
- right1 = -1;
- }
- ybig1 = floor(MyPoint.y1d + 0.5);
- ysmall1 = MyPoint.y1d - (double)ybig1;
- if (ysmall1 > 0) {
- down1 = swidth;
- }
- else {
- ysmall1 = -ysmall1;
- down1 = -swidth;
- }
- offset1 = ybig1*swidth+xbig1;
- a1 = 1.0 + (xsmall1 * ysmall1) - xsmall1 - ysmall1;
- b1 = xsmall1 * (1.0 - ysmall1);
- c1 = ysmall1 * (1.0 - xsmall1);
- d1 = xsmall1 * ysmall1;
- (*arrayr) = min(max((((ULONG)
- ((((double) Pic1.red[offset])*a + ((double) Pic1.red[offset+right])*bb+
- ((double) Pic1.red[offset+down])*c+((double) Pic1.red[offset+down+right])*d)*((double)r) +
- (((double) Pic2.red[offset1])*a1 + ((double) Pic2.red[offset1+right1])*b1+
- ((double) Pic2.red[offset1+down1])*c1+((double) Pic2.red[offset1+down1+right1])*d1)*((double)r2))
- )>>10) + rplus - rminus,0),255);
- (*arrayg) = min(max((((ULONG)
- ((((double)Pic1.green[offset])*a + ((double)Pic1.green[offset+right])*bb+
- ((double)Pic1.green[offset+down])*c+((double)Pic1.green[offset+down+right])*d)*((double)g) +
- (((double)Pic2.green[offset1])*a1 + ((double)Pic2.green[offset1+right1])*b1+
- ((double)Pic2.green[offset1+down1])*c1+((double)Pic2.green[offset1+down1+right1])*d1)*((double)g2))
- )>>10) + gplus - gminus,0),255);
- (*arrayb) = min(max((((ULONG)
- ((((double) Pic1.blue[offset])*a + ((double) Pic1.blue[offset+right])*bb+
- ((double) Pic1.blue[offset+down])*c+((double) Pic1.blue[offset+down+right])*d)*((double)b) +
- (((double) Pic2.blue[offset1])*a1 + ((double) Pic2.blue[offset1+right1])*b1+
- ((double) Pic2.blue[offset1+down1])*c1+((double) Pic2.blue[offset1+down1+right1])*d1)*((double)b2))
- )>>10) + bplus - bminus,0),255);
- }
- else {
- (*arrayr) = min(max(((ULONG)
- (((((double)Pic1.red[offset])*a + ((double)Pic1.red[offset+right])*bb+
- ((double)Pic1.red[offset+down])*c+((double)Pic1.red[offset+down+right])*d)
- )*((double)r))>>10) + rplus - rminus,0),255);
- (*arrayg) = min(max(((ULONG)
- (((((double)Pic1.green[offset])*a + ((double)Pic1.green[offset+1])*bb+
- ((double)Pic1.green[offset+down])*c+((double)Pic1.green[offset+down+right])*d)
- )*((double)g))>>10) + gplus - gminus,0),255);
- (*arrayb) = min(max(((ULONG)
- (((((double)Pic1.blue[offset])*a + ((double)Pic1.blue[offset+1])*bb+
- ((double)Pic1.blue[offset+down])*c+((double)Pic1.blue[offset+down+right])*d)
- )*((double)b))>>10) + bplus - bminus,0),255);
- }
- }
- else {
- // Calculate new colours (without AntiAlias)
- offset = MyPoint.y*swidth+MyPoint.x;
- if ((Single == 1) || (Single == 3)) {
- (*arrayr) = min(max(((Pic1.red[offset]*r)>>10) + rplus - rminus,0),255);
- (*arrayg) = min(max(((Pic1.green[offset]*g)>>10) + gplus - gminus,0),255);
- (*arrayb) = min(max(((Pic1.blue[offset]*b)>>10) + bplus - bminus,0),255);
- }
- else {
- offset1 = MyPoint.y1*swidth+MyPoint.x1;
- (*arrayr) = min(max((((Pic2.red[offset1]*r2) +
- (Pic1.red[offset]*r))>>10) + rplus - rminus,0),255);
- (*arrayg) = min(max((((Pic2.green[offset1]*g2) +
- (Pic1.green[offset]*g))>>10) + gplus - gminus,0),255);
- (*arrayb) = min(max((((Pic2.blue[offset1]*b2) +
- (Pic1.blue[offset]*b))>>10) + bplus - bminus,0),255);
- }
- }
- // If we are skipping columns then copy colour forward
- if (DX) {
- xr = *arrayr;
- xg = *arrayg;
- xb = *arrayb;
- x++;
- for (myx = 0;
- (myx < DX) && (x < width);
- x++,myx++) {
- if (Mode & MODE_ONCE) {
- Points += (Depth+4);
- }
- arrayr++;
- *arrayr = xr;
- arrayg++;
- *arrayg = xg;
- arrayb++;
- *arrayb = xb;
- }
- x--;
- }
- // next column (if not already there)
- if (x < width) {
- arrayr++;
- arrayg++;
- arrayb++;
- }
- }
- // end of line, check 'Stop' and 'Help'
- OkFlag = HandleProgressIDCMP();
- if (handle) {
- while (agm = GetAmigaGuideMsg(handle)) {
- ReplyAmigaGuideMsg(agm);
- }
- }
- // skip part word at end of line
- arrayr += (swidth - width);
- arrayg += (swidth - width);
- arrayb += (swidth - width);
- if (EGS_Win) {
- CopyEGS(y,&er,&eg,&eb);
- }
- // if skipping lines then copy previous line
- if (DY) {
- y++;
- for (myy = 0;
- (myy < DY) && (y<height);
- y++, myy++) {
- memcpy(arrayr, arrayr - swidth, swidth);
- arrayr += swidth;
- memcpy(arrayg, arrayg - swidth, swidth);
- arrayg += swidth;
- memcpy(arrayb, arrayb - swidth, swidth);
- arrayb += swidth;
- if (EGS_Win) {
- CopyEGS(y,&er,&eg,&eb);
- }
- if (Mode & MODE_ONCE) {
- Points += ((Depth+4)*width);
- }
- }
- y--;
- }
- }
- if ((Mode & MODE_DELAU) && (!MODE_ONCE)) {
- FreeTriangles();
- }
- // not ok - already displayed an error
- if (!OkFlag) {
- e = (char *)-1;
- }
- else {
- // Save image
- OkFlag = SaveFile();
- // Caclulate time (if we have not already)
- if (TimerBase) {
- GetSysTime(&time2);
- t2 = TRUE;
- SubTime(&time2,&time1);
- }
- // Not ok - already displayed error message
- if (!OkFlag) {
- e = (char *)-1;
- }
- }
- }
- }
- if (OkFlag && ((Single == 0) || (Single == 2))) {
- // Pass to ARexx for processing
- if (strcmp(Prescript,"OFF")) {
- AddMessage("Prescript for last frame");
- f = Frames+1;
- Do = 0;
- strcpy(buffer,Prescript);
- strcat(buffer," %ld");
- sprintf(buffer1,buffer,&Arexx);
- OkFlag = !SendRxMsg(buffer1,FALSE);
- if (!OkFlag) {
- e = (char *)-1;
- }
- if (OkFlag && Do && ((!Pic1_Open) || (Single == 2))) {
- if (Pic2_Open) {
- Close24bit(&Pic2);
- Pic2_Open = FALSE;
- }
- if (Pic1_Open) {
- Close24bit(&Pic1);
- Pic1_Open = FALSE;
- }
- OkFlag = LoadFrames(FALSE,FALSE,TRUE);
- if (!OkFlag) {
- e = (char *)-1;
- }
- }
- if (OkFlag && Do) {
- AddMessage("Saving last frame");
- memcpy(RED,Pic2.red,swidth*height);
- memcpy(GREEN,Pic2.green,swidth*height);
- memcpy(BLUE,Pic2.blue,swidth*height);
- OkFlag = SaveFile();
- if (!OkFlag) {
- e = (char *)-1;
- }
- }
- }
- }
- }
- AddMessage("Cleaning up");
- if ((Mode & MODE_DELAU) && (MODE_ONCE)) {
- FreeTriangles();
- }
- DeleteAllPoints();
- if (RED) FreeVec(RED);
- if (GREEN) FreeVec(GREEN);
- if (BLUE) FreeVec(BLUE);
- if (OScrn) {
- FreeScreen24(OScrn);
- }
- else { // Should not need this if else
- if (!PPM) {
- if (Planes[0]) FreeRaster(Planes[0],width,height);
- if (Planes[1]) FreeRaster(Planes[1],width,height);
- if (Planes[2]) FreeRaster(Planes[2],width,height);
- if (!DCTV3) {
- if (Planes[3]) FreeRaster(Planes[3],width,height);
- if (!BW16 && !DCTV4) {
- if (Planes[4]) FreeRaster(Planes[4],width,height);
- if (Planes[5]) FreeRaster(Planes[5],width,height);
- if (!HAM6) {
- if (Planes[6]) FreeRaster(Planes[6],width,height);
- if (Planes[7]) FreeRaster(Planes[7],width,height);
- if (!HAM8 && !BW256) {
- if (Planes[8]) FreeRaster(Planes[8],width,height);
- if (Planes[9]) FreeRaster(Planes[9],width,height);
- if (Planes[10]) FreeRaster(Planes[10],width,height);
- if (Planes[11]) FreeRaster(Planes[11],width,height);
- if (Planes[12]) FreeRaster(Planes[12],width,height);
- if (Planes[13]) FreeRaster(Planes[13],width,height);
- if (Planes[14]) FreeRaster(Planes[14],width,height);
- if (Planes[15]) FreeRaster(Planes[15],width,height);
- if (Planes[16]) FreeRaster(Planes[16],width,height);
- if (Planes[17]) FreeRaster(Planes[17],width,height);
- if (Planes[18]) FreeRaster(Planes[18],width,height);
- if (Planes[19]) FreeRaster(Planes[19],width,height);
- if (Planes[20]) FreeRaster(Planes[20],width,height);
- if (Planes[21]) FreeRaster(Planes[21],width,height);
- if (Planes[22]) FreeRaster(Planes[22],width,height);
- if (Planes[23]) FreeRaster(Planes[23],width,height);
- }
- }
- }
- }
- }
- }
- if (!Alloced && !e) {
- e = "Error AllocVec for output";
- e1 = NULL;
- hnum = H_AllocVec;
- }
- }
- else {
- e = (char *)-1;
- }
- if (OkFlag) {
- e = (char *)-1;
- }
- if (!e) {
- e = "Error Opening points file";
- e1 = NULL;
- hnum = H_OpenPoints;
- }
- if (Pic2_Open) {
- Close24bit(&Pic2);
- Pic2_Open = FALSE;
- }
- if (Pic1_Open) {
- Close24bit(&Pic1);
- Pic1_Open = FALSE;
- }
- if (plane0) MyFreeVec(plane0);
- if (plane1) MyFreeVec(plane1);
- if (plane2) MyFreeVec(plane2);
- if (plane3) MyFreeVec(plane3);
- if (plane4) MyFreeVec(plane4);
- if (plane5) MyFreeVec(plane5);
- if (plane6) MyFreeVec(plane6);
- if (plane7) MyFreeVec(plane7);
- // reset requesters
- process->pr_WindowPtr = oldWindowPtr;
- }
- else {
- e = "Error opening progress window";
- e1 = NULL;
- hnum = H_Progress;
- }
- // close down everything
- CloseProgressWindow();
- CloseDownScreen();
- MyArgArrayDone();
- if (EGS) {
- if (EGS_Win) {
- EI_CloseWindow(EGS_Win);
- }
- if (EGS_BitMap) {
- E_DisposeBitMap(EGS_BitMap);
- }
- }
- if (EGSIntuiBase) {
- CloseLibrary(EGSIntuiBase);
- }
- if (EGSGfxBase) {
- CloseLibrary(EGSGfxBase);
- }
- if (EGSBase) {
- CloseLibrary(EGSBase);
- }
- CloseLibrary(DiskfontBase);
- }
- if (!e) {
- e = "Unable to Open %s";
- e1 = "diskfont.library(36)";
- hnum = H_Library;
- }
- CloseLibrary(IconBase);
- }
- if (!e) {
- e = "Unable to Open %s";
- e1 = "icon.library(37)";
- hnum = H_Library;
- }
- CloseLibrary(UtilityBase);
- }
- if (!e) {
- e = "Unable to Open %s";
- e1= "utility.library(37)";
- hnum = H_Library;
- }
- CloseLibrary(AslBase);
- }
- if (!e) {
- e = "Unable to Open %s";
- e1 = "asl.library(37)";
- hnum = H_Library;
- }
- CloseLibrary(GadToolsBase);
- }
- if (!e) {
- e = "Unable to Open %s";
- e1 = "gadtools.library(37)";
- hnum = H_Library;
- }
- CloseLibrary(LayersBase);
- }
- if (!e) {
- e = "Unable to Open %s";
- e1 = "layers.library(37)";
- hnum = H_Library;
- }
- CloseLibrary(GfxBase);
- }
- if (!e) {
- e = "Unable to Open %s";
- e1 = "graphics.library(37)";
- hnum = H_Library;
- }
- CloseLibrary(IFFParseBase);
- }
- if (!e) {
- e = "Unable to Open %s";
- e1 = "iffparse.library(37)";
- hnum = H_Library;
- }
- CloseLibrary(RexxSysBase);
- }
- if (!e) {
- e = "Unable to Open %s";
- e1 = "rexxsyslib.library(0)";
- hnum = H_Library;
- }
- // Display an error message
- if (e != (char *)-1) {
- Error(e,"Quit",e1,hnum);
- }
- }
- if (OpalBase) {
- CloseLibrary((struct Library *)OpalBase);
- }
- if (TimerBase) {
- CloseDevice((struct IORequest *) &tr);
- }
- if (AmigaGuideBase) {
- if (handle) {
- CloseAmigaGuide(handle);
- }
- CloseLibrary(AmigaGuideBase);
- }
- if (NoFragBase) {
- FreeMemoryChain(Chain,TRUE);
- CloseLibrary((struct Library *)NoFragBase);
- }
- if (DCTVBase) {
- CloseLibrary(DCTVBase);
- }
- if (ReqToolsBase) {
- CloseLibrary(ReqToolsBase);
- }
- if (IntuitionBase) {
- CloseLibrary((struct Library *)IntuitionBase);
- }
- return 0;
- }
-
- extern UWORD FileFormat = 0;
-
- /* recognized file formats */
- #define FORMAT_IFF 1
- #define FORMAT_JPEG 2
- #define FORMAT_GIF 3
- #define FORMAT_PPM 4
- #define FORMAT_TARGA 5
-
- /* Opens a 24 bit image
- * filename = name of file
- * pic = structure to update
- * GUI = TRUE to display error message
- * Returns TRUE if ok
- */
- BOOL
- Load24bit(char *filename,struct Picture *pic,BOOL GUI) {
- char *e = NULL; // Error message main text
- char *e1 = NULL; // sub text,
- struct RastPort RP, // Rastport
- TRP; // Temp rastport
- struct BitMap BM, // Bitmap
- TBM; // Temp bitmap
- ULONG hnum = 0; // Help on error
- BOOL OkFlag=TRUE; // Still OK?
- char buffer[256], // For Rexx Scripts
- buffer1[256];
- long Err; // Opal error
- BPTR fh;
- UBYTE zbuffer[5]="\0\0\0\0";
- decompress_info_ptr info; // Load JPEG stuff
- UWORD i,j;
- LONG penno;
- struct RastPort Rp; // Rast port for conversion
- UBYTE *rx,*gx,*bx;
- UBYTE rr,gg,bb;
- UWORD EHB;
- BOOL isHAM6 = FALSE;
- BOOL isHAM8 = FALSE;
- BOOL isEHB = FALSE;
- struct DisplayInfo queryinfo;
- DisplayInfoHandle dhandle;
- struct DCTVCvtHandle *chandle; // DCTV conversion stuff
- UWORD *DCTVcolors; // DCTV palette
-
- if (filename) {
- // Load image processing
- if (strcmp(Loadscript,"OFF")) {
- strcpy(buffer,Loadscript);
- strcat(buffer," %ld %ld %ld %ld %s");
- sprintf(buffer1,buffer,f+Start-1,Frames,Single,(pic==&Pic1)?0:1,filename);
- AddMessage("Loadscript processing");
- OkFlag = !SendRxMsg(buffer1,FALSE);
- if (!OkFlag) {
- e = (char *)-1;
- GUI = FALSE; // Do not display error
- }
- }
- pic->rgbonelot = FALSE;
- if (!e) {
- // determine file format
- if (fh = Open(filename,MODE_OLDFILE)) {
- FRead(fh,zbuffer,4,1);
- if ((!strcmp(zbuffer,"FORM")) ||
- (!strcmp(zbuffer,"CAT ")) ||
- (!strcmp(zbuffer,"LIST"))) {
- FileFormat = FORMAT_IFF;
- }
- else {
- if ((zbuffer[0] == 0xFF) &&
- (zbuffer[1] == 0xD8)) {
- FileFormat = FORMAT_JPEG;
- }
- else {
- if ((zbuffer[0] == 'G') &&
- (zbuffer[1] == 'I') &&
- (zbuffer[2] == 'F')) {
- FileFormat = FORMAT_GIF;
- }
- else {
- if ((zbuffer[0] == 'P') &&
- ((zbuffer[1] == '2') ||
- (zbuffer[1] == '3') ||
- (zbuffer[1] == '5') ||
- (zbuffer[1] == '6'))) {
- FileFormat = FORMAT_PPM;
- }
- else {
- FileFormat = FORMAT_TARGA;
- }
- }
- }
- }
- Close(fh);
- }
- else {
- e = "Error opening file '%s'";
- e1 = filename;
- hnum = H_Open;
- OkFlag = FALSE;
- }
- }
- if (OkFlag) {
- AddMessage((pic == &Pic2)?"Loading image 2":"Loading image 1");
- }
- // We have a file name
- if (OkFlag && (FileFormat != FORMAT_IFF)) {
- // Not an IFF file so use JPEG code
- AddMessage((FileFormat == FORMAT_JPEG)?"Loading JFIF":
- (FileFormat == FORMAT_GIF)?"Loading GIF":
- (FileFormat == FORMAT_PPM)?"Loading PPM":
- (FileFormat == FORMAT_TARGA)?"Loading Targa?":
- "Loading ?");
- if ((info = LoadJPEG(filename,0,NULL,NULL,NULL,NULL)) &&
- (info->output_file)) {
- AddMessage("Allocating work memory");
- pic->rgbonelot = TRUE;
- pic->red = (UBYTE *)info->output_file;
- pic->green = pic->red + (((info->image_width+15)>>4)<<4) * info->image_height;
- pic->blue = pic->green + (((info->image_width+15)>>4)<<4) * info->image_height;
- // Allocate temp bit maps if first image and no OpalVision save
- if ((OVFormat) || (plane0) ||
- ((plane0 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane1 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane2 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane3 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane4 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane5 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane6 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane7 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)))) {
- return TRUE;
- }
- else {
- e = "Unable to %s";
- e1 = "allocate memory for bitmap";
- hnum = H_AllocPlanes;
- }
- }
- }
- if (OkFlag && (FileFormat == FORMAT_IFF)) {
- // Load iff
- AddMessage("Loading IFF");
- if (pic->ilbm = (struct ILBMInfo *)MyAllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
- // IFF stuff
- if (pic->ilbm->ParseInfo.iff = AllocIFF()) {
- // more iff stuff
- pic->ilbm->ParseInfo.propchks = props;
- pic->ilbm->ParseInfo.collectchks = nowt;
- pic->ilbm->ParseInfo.stopchks = stops;
- // Load the image using IFF routines
- if (!(loadbrush(pic->ilbm,filename))) {
- // Close the file and validate
- closeifile(&(pic->ilbm->ParseInfo));
- pwidth = width < 320 ? 320 : width;
- pheight = height < 200 ? 200 : height;
- pmode = pwidth >= 640 ? HIRES : 0L;
- pmode |= pheight >= 400 ? LACE : 0L;
- // ?????? width = pic->ilbm->Bmhd.w;
- // Allocate chunky bit maps
- AddMessage("Allocating Bitmaps");
- if ((pic->red = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),MEMF_CLEAR)) &&
- (pic->green = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),MEMF_CLEAR)) &&
- (pic->blue = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),MEMF_CLEAR)) &&
- // Allocate temp bit maps if first image and no OpalVision save
- ((OVFormat && (pic->ilbm->Bmhd.nPlanes != 24)) || (plane0) ||
- ((plane0 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane1 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane2 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane3 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane4 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane5 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane6 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane7 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR))))) {
- if (pic->ilbm->Bmhd.nPlanes == 24) {
- // Convert 24 bit planar to chunky
- AddMessage("Converting 24 bit to Chunky");
- // Initialise rast ports/bitmaps
- InitRastPort(&RP);
- InitRastPort(&TRP);
- InitBitMap(&TBM,8,pic->ilbm->Bmhd.w,1);
- TRP.BitMap = &TBM;
- TBM.Planes[0]=plane0;
- TBM.Planes[1]=plane1;
- TBM.Planes[2]=plane2;
- TBM.Planes[3]=plane3;
- TBM.Planes[4]=plane4;
- TBM.Planes[5]=plane5;
- TBM.Planes[6]=plane6;
- TBM.Planes[7]=plane7;
- InitBitMap(&BM,8,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h);
- RP.BitMap = &BM;
- BM.Planes[0] = pic->ilbm->brbitmap->Planes[0];
- BM.Planes[1] = pic->ilbm->brbitmap->Planes[1];
- BM.Planes[2] = pic->ilbm->brbitmap->Planes[2];
- BM.Planes[3] = pic->ilbm->brbitmap->Planes[3];
- BM.Planes[4] = pic->ilbm->brbitmap->Planes[4];
- BM.Planes[5] = pic->ilbm->brbitmap->Planes[5];
- BM.Planes[6] = pic->ilbm->brbitmap->Planes[6];
- BM.Planes[7] = pic->ilbm->brbitmap->Planes[7];
- // Convert red to chunky
- ReadPixelArray8(&RP,0,0,pic->ilbm->Bmhd.w-1,pic->ilbm->Bmhd.h-1,pic->red,&TRP);
- WaitBlit();
- BM.Planes[0] = pic->ilbm->brbitmap->Planes[8];
- BM.Planes[1] = pic->ilbm->brbitmap->Planes[9];
- BM.Planes[2] = pic->ilbm->brbitmap->Planes[10];
- BM.Planes[3] = pic->ilbm->brbitmap->Planes[11];
- BM.Planes[4] = pic->ilbm->brbitmap->Planes[12];
- BM.Planes[5] = pic->ilbm->brbitmap->Planes[13];
- BM.Planes[6] = pic->ilbm->brbitmap->Planes[14];
- BM.Planes[7] = pic->ilbm->brbitmap->Planes[15];
- // and green
- ReadPixelArray8(&RP,0,0,pic->ilbm->Bmhd.w-1,pic->ilbm->Bmhd.h-1,pic->green,&TRP);
- WaitBlit();
- BM.Planes[0] = pic->ilbm->brbitmap->Planes[16];
- BM.Planes[1] = pic->ilbm->brbitmap->Planes[17];
- BM.Planes[2] = pic->ilbm->brbitmap->Planes[18];
- BM.Planes[3] = pic->ilbm->brbitmap->Planes[19];
- BM.Planes[4] = pic->ilbm->brbitmap->Planes[20];
- BM.Planes[5] = pic->ilbm->brbitmap->Planes[21];
- BM.Planes[6] = pic->ilbm->brbitmap->Planes[22];
- BM.Planes[7] = pic->ilbm->brbitmap->Planes[23];
- // and blue
- ReadPixelArray8(&RP,0,0,pic->ilbm->Bmhd.w-1,pic->ilbm->Bmhd.h-1,pic->blue,&TRP);
- WaitBlit();
- AddMessage("Cleaning up");
- // Set up stuff to write image
- // ???? width = pic->ilbm->Bmhd.w;
- // ???? height = pic->ilbm->Bmhd.h;
- // Unload everything and exit cleanly
- unloadbrush(pic->ilbm);
- FreeIFF(pic->ilbm->ParseInfo.iff);
- MyFreeMem(pic->ilbm,sizeof(struct ILBMInfo));
- return TRUE;
- }
- else {
- if (DCTVBase && TestDCTVSignature(pic->ilbm->brbitmap)) {
- // Convert DCTV to chunky
- if (DCTVcolors = MyAllocVec(2L<<pic->ilbm->Bmhd.nPlanes,MEMF_CLEAR)) {
- for (i=0; i < (1L<<pic->ilbm->Bmhd.nPlanes); ++i) {
- DCTVcolors[i] = ((pic->ilbm->RGB[i*4+1] & 0xf0) << 4) |
- ((pic->ilbm->RGB[i*4+2] & 0xf0)) |
- ((pic->ilbm->RGB[i*4+3] & 0xf0) >> 4);
- }
- AddMessage("Converting DCTV to Chunky");
- if (chandle = AllocDCTVCvtTags(pic->ilbm->brbitmap,
- DCTVCVTA_Type, DCTVCVTT_DCTVtoRGB,
- DCTVCVTA_Width, (((pic->ilbm->Bmhd.w+15)>>4)<<4),
- DCTVCVTA_Height, pic->ilbm->Bmhd.h,
- DCTVCVTA_Flags, ((pic->ilbm->camg & LACE)?DCTVCVTF_Lace:0)|
- DCTVCVTF_CustomRGBBuf,
- DCTVCVTA_ColorTable, DCTVcolors,
- TAG_END)) {
- chandle->Red = pic->red;
- chandle->Green = pic->green;
- chandle->Blue = pic->blue;
- while (chandle->DstLineNum < chandle->Height) {
- CvtDCTVLine(chandle);
- if ((chandle->DstLineNum > 0) &&
- (chandle->DstLineNum <= chandle->Height)) {
- chandle->Red += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
- chandle->Green += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
- chandle->Blue += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
- }
- }
- MyFreeVec(DCTVcolors);
- FreeDCTVCvt(chandle);
- // Unload everything and exit cleanly
- unloadbrush(pic->ilbm);
- FreeIFF(pic->ilbm->ParseInfo.iff);
- MyFreeMem(pic->ilbm,sizeof(struct ILBMInfo));
- return TRUE;
- }
- MyFreeVec(DCTVcolors);
- }
- }
- else {
- // determine special IFF mode
- if ((dhandle = FindDisplayInfo(pic->ilbm->camg)) &&
- (GetDisplayInfoData(dhandle,(UBYTE *)&queryinfo,sizeof(queryinfo),DTAG_DISP,NULL))) {
- if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
- AddMessage("Converting HAM6 to Chunky");
- isHAM6 = TRUE;
- }
- else {
- if ((pic->ilbm->Bmhd.nPlanes == 8) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
- isHAM8 = TRUE;
- AddMessage("Converting HAM8 to Chunky");
- }
- else {
- if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_EXTRAHALFBRITE)) {
- isEHB = TRUE;
- AddMessage("Converting EHB to Chunky");
- }
- else {
- AddMessage("Converting ILBM to Chunky");
- }
- }
- }
- }
- // Convert to chunky
- InitRastPort(&Rp);
- Rp.BitMap = pic->ilbm->brbitmap;
- rx = pic->red;
- gx = pic->green;
- bx = pic->blue;
- // For each line
- for (j = 0;
- j < height;
- ++j) {
- // Convert each column
- // Note: this is very ineffecient in that it uses
- // ReadPixel().
- // But the cost is fairly small compared to the render time
- if (isHAM6) {
- rr = gg = bb = 0;
- for (i = 0;
- i < width;
- ++i) {
- penno = ReadPixel(&Rp,i,j);
- switch (penno & 0x30) {
- case 0:
- *rx++ = rr = pic->ilbm->RGB[penno*4+1];
- *gx++ = gg = pic->ilbm->RGB[penno*4+2];
- *bx++ = bb = pic->ilbm->RGB[penno*4+3];
- break;
- case 0x10:
- *rx++ = rr;
- *gx++ = gg;
- *bx++ = bb = (penno&0xf)|((penno&0xf)<<4);
- break;
- case 0x20:
- *rx++ = rr = (penno&0xf)|((penno&0xf)<<4);
- *gx++ = gg;
- *bx++ = bb;
- break;
- case 0x30:
- *rx++ = rr;
- *gx++ = gg = (penno&0xf)|((penno&0xf)<<4);
- *bx++ = bb;
- break;
- }
- }
- }
- else {
- if (isHAM8) {
- rr = gg = bb = 0;
- for (i = 0;
- i < width;
- ++i) {
- penno = ReadPixel(&Rp,i,j);
- switch (penno & 0xc0) {
- case 0:
- *rx++ = rr = pic->ilbm->RGB[penno*4+1];
- *gx++ = gg = pic->ilbm->RGB[penno*4+2];
- *bx++ = bb = pic->ilbm->RGB[penno*4+3];
- break;
- case 0x40:
- *rx++ = rr;
- *gx++ = gg;
- *bx++ = bb = (penno&0x3f)<<2;
- break;
- case 0x80:
- *rx++ = rr = (penno&0x3f)<<2;
- *gx++ = gg;
- *bx++ = bb;
- break;
- case 0xc0:
- *rx++ = rr;
- *gx++ = gg = (penno&0x3f)<<2;
- *bx++ = bb;
- break;
- }
- }
- }
- else {
- if (isEHB) {
- for (i = 0;
- i < width;
- ++i) {
- penno = ReadPixel(&Rp,i,j);
- EHB = (penno & 0x20)?1:0;
- penno &= 0x1f;
- *rx++ = pic->ilbm->RGB[penno*4+1]>>EHB;
- *gx++ = pic->ilbm->RGB[penno*4+2]>>EHB;
- *bx++ = pic->ilbm->RGB[penno*4+3]>>EHB;
- }
- }
- else {
- for (i = 0;
- i < width;
- ++i) {
- penno = ReadPixel(&Rp,i,j);
- *rx++ = pic->ilbm->RGB[penno*4+1];
- *gx++ = pic->ilbm->RGB[penno*4+2];
- *bx++ = pic->ilbm->RGB[penno*4+3];
- }
- }
- }
- }
- rx += ((((width+15)>>4)<<4)-width);
- gx += ((((width+15)>>4)<<4)-width);
- bx += ((((width+15)>>4)<<4)-width);
- }
- AddMessage("Cleaning up");
- unloadbrush(pic->ilbm);
- FreeIFF(pic->ilbm->ParseInfo.iff);
- MyFreeMem(pic->ilbm,sizeof(struct ILBMInfo));
- return TRUE;
- }
- }
- }
- if (!e) {
- e = "Unable to %s";
- e1 = "allocate memory for bitmap";
- hnum = H_AllocPlanes;
- }
- }
- if (!e) {
- e = "Error loading '%s'";
- e1 = filename;
- hnum = H_Load;
- }
- unloadbrush(pic->ilbm);
- FreeIFF(pic->ilbm->ParseInfo.iff);
- }
- if (!e) {
- e = "Unable to %s";
- e1 = "AllocIFF";
- hnum = H_AllocIFF;
- }
- MyFreeMem(pic->ilbm,sizeof(struct ILBMInfo));
- }
- if (!e) {
- e = "Unable to '%s'";
- e1 = "AllocMem for ILBMInfo";
- hnum = H_AllocILBM;
- }
- }
- if (OkFlag && OpalBase) {
- // If we still have not loaded the image then try opal.library as a last resort
- AddMessage("Loading using opal.library");
- Err = LoadImage24(NULL,filename,VIRTUALSCREEN24|FORCE24);
- if (Err < OL_ERR_MAXERR) {
- switch (Err) {
- case OL_ERR_OUTOFMEM:
- e = "Failure - Out of memory - loading '%s'";
- break;
- case OL_ERR_OPENFILE:
- e = "Failure - Opening file - loading '%s'";
- break;
- case OL_ERR_FORMATUNKNOWN:
- e = "Failure - Unknown Format - loading '%s'";
- break;
- case OL_ERR_NOTILBM:
- e = "Failure - Not an ILBM file - loading '%s'";
- break;
- case OL_ERR_FILEREAD:
- e = "Failure - Reading file - loading '%s'";
- break;
- case OL_ERR_BADIFF:
- e = "Failure - Bad IFF Format - loading '%s'";
- break;
- case OL_ERR_CANTCLOSE:
- e = "Failure - Can not Close - loading '%s'";
- break;
- case OL_ERR_BADJPEG:
- e = "Failure - Bad JPEG Format - loading '%s'";
- break;
- case OL_ERR_UNSUPPORTED:
- e = "Failure - Unsupported Format - loading '%s'";
- break;
- case OL_ERR_CTRLC:
- case OL_ERR_NOTHUMBNAIL:
- case OL_ERR_OPENSCREEN:
- case OL_ERR_FILEWRITE:
- default:
- e = "Failure - Unknown problem - loading '%s'";
- break;
- }
- e1 = filename;
- hnum = HE_OpalVision;
- }
- else {
- AddMessage("Allocating Bitmaps");
- pic->OScrn = (struct OpalScreen *)Err;
- // Allocate chunky bit maps
- if ((pic->red = AllocVec(((((pic->OScrn->Width+15)>>4)<<4)*pic->OScrn->Height),MEMF_CLEAR)) &&
- (pic->green = AllocVec(((((pic->OScrn->Width+15)>>4)<<4)*pic->OScrn->Height),MEMF_CLEAR)) &&
- (pic->blue = AllocVec(((((pic->OScrn->Width+15)>>4)<<4)*pic->OScrn->Height),MEMF_CLEAR)) &&
- // Allocate temp bit maps if first image and no OpalVision save
- ((OVFormat) || (plane0) ||
- ((plane0 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane1 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane2 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane3 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane4 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane5 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane6 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR)) &&
- (plane7 = MyAllocVec((((width+15)>>4)<<4),MEMF_CHIP|MEMF_CLEAR))))) {
- AddMessage("Converting Opal to Chunky");
- OVtoRGB(pic->OScrn,&(pic->red),0,0,((pic->OScrn->Width+15)>>4)<<4,pic->OScrn->Height);
- }
- else {
- e = "Unable to %s";
- e1 = "allocate memory for bitmap";
- hnum = H_AllocPlanes;
- }
- FreeScreen24(pic->OScrn);
- if (!e) {
- return TRUE;
- }
- }
- }
- else {
- if (!e) {
- e = "No opal.library";
- hnum = HE_NoOpal;
- }
- }
- }
- Close24bit(pic);
- // Display an error message if required
- if (GUI)
- Error(e,"Quit",e1,hnum);
- return(FALSE);
- }
-
- /* Close an image clearing everything down */
- void
- Close24bit(struct Picture *pic) {
- if (pic) {
- if (pic->rgbonelot) {
- if (pic->red) {
- FreeVec(pic->red);
- }
- pic->red = NULL;
- pic->green = NULL;
- pic->blue = NULL;
- }
- else {
- if (pic->red) {
- FreeVec(pic->red);
- pic->red = NULL;
- }
- if (pic->green) {
- FreeVec(pic->green);
- pic->green = NULL;
- }
- if (pic->blue) {
- FreeVec(pic->blue);
- pic->blue = NULL;
- }
- }
- }
- }
-
- /* Open a file
- * Returns : TRUE if ok
- * filename : name of file, or NULL for requester
- */
- BOOL
- MyOpen(char *filename,BOOL JustPoints) {
- char dirname[257];
- char rtfilename[108] = "\0"; // reqtools filename from requester
- char *ifilename=NULL;
- BOOL ok=TRUE;
- BPTR fh;
- char buffer[257];
- LONG w,h;
- LONG xx,x1,yy,y1;
- UWORD i; // General index
-
- struct FileRequester *filereq; // For file requester
- struct rtFileRequester *rtfilereq;
- struct MyPoint *MyPoint;
- // If filename supplied then use it otherwise use file requester
- if (filename) {
- ifilename = filename;
- }
- else {
- if (MatchToolValue(MyArgString("REQTOOLS","YES",FALSE),"ALL") &&
- (rtfilereq = (struct rtFileRequester *)rtAllocRequestA(RT_FILEREQ,NULL))) {
- if (rtFileRequestA(rtfilereq,rtfilename,"TSMorph-render - Pick project",NULL)) {
- strncpy(dirname,rtfilereq->Dir,256);
- if (AddPart(dirname,rtfilename,256)) {
- ifilename=dirname;
- }
- }
- rtFreeRequest(rtfilereq);
- }
- else {
- if (filereq = (struct FileRequester *)AllocFileRequest()) {
- if (AslRequestTags((APTR) filereq,ASL_Hail,(Tag) "TSMorph-render - Pick project",TAG_DONE)) {
- strncpy(dirname,filereq->rf_Dir,256);
- if (AddPart(dirname,filereq->rf_File,256)) {
- ifilename=dirname;
- }
- }
- FreeFileRequest(filereq);
- }
- }
- }
- // If user did not cancel
- if (ifilename) {
- OpenNewArgs(ifilename); // Load new parameters
- // Open file and skip the WB displayable names
- if (fh=Open(ifilename,MODE_OLDFILE)) {
- FGets(fh,buffer,256);
- if (JustPoints && strcmp(buffer,"TSMorph 2.0\n")) {
- Error("Invalid file format\nLine '%s'","Quit",buffer,H_FileFormat);
- ok = FALSE;
- }
- else {
- if (!JustPoints) {
- Pic1.filename[0]=0;
- Pic2.filename[0]=0;
- // Keep file name
- strcpy(MyFileName,ifilename);
- strcat(MyFileName,".%03ld");
- if (strcmp(buffer,"TSMorph 1.2\n")) {
- Error("Assuming version 1.0 file format","OK",NULL,HE_OldFormat);
- }
- else {
- FGets(fh,buffer,256);
- }
- if (strlen(buffer)) {
- buffer[strlen(buffer)-1]=0;
- }
- strcpy(Pic1.filename,buffer);
- FGets(fh,buffer,256);
- if (strlen(buffer)) {
- buffer[strlen(buffer)-1]=0;
- }
- strcpy(Pic2.filename,buffer);
- // Get file name, set progress and try and load image
- FGets(fh,buffer,256);
- if (strlen(buffer)) {
- buffer[strlen(buffer)-1]=0;
- }
- if (buffer[0]) {
- strcpy(Pic1.filename,buffer);
- }
- FGets(fh,buffer,256);
- if (strlen(buffer)) {
- buffer[strlen(buffer)-1]=0;
- }
- if (buffer[0]) {
- strcpy(Pic2.filename,buffer);
- }
- // Loaded both so get anim name
- FGets(fh,AnimName,256);
- if (strlen(AnimName)) {
- AnimName[strlen(AnimName)-1]=0;
- }
- // Read and validate general information
- FGets(fh,buffer,256);
- if (ok && (sscanf(buffer,"w=%ld,h=%ld,Frames=%ld,Single=%ld,Start=%ld",&w,&h,&Frames,&Single,&Start) != 5)) {
- Error("Invalid file format\nLine '%s'","Quit",buffer,H_FileFormat);
- }
- else {
- width = w; // ???????
- height = h; // ???????
- if (ok &&
- ((w != width) ||
- (h != height))) {
- Error("Size does not match image\nLine '%s'","Quit",buffer,H_SizeMatch);
- ok = FALSE;
- }
- }
- }
- }
- if (ok) {
- PointCount = 0;
- // Read and store all the points
- while (ok &&
- FGets(fh,buffer,256) &&
- (sscanf(buffer,"x=%ld,y=%ld,x1=%ld,y1=%ld",&xx,&yy,&x1,&y1) == 4)) {
- if ((xx<0)||(xx>(width-1)) ||
- (yy<0)||(yy>(height-1))) {
- Error("Point out of range\nLine '%s'","Quit",buffer,H_Range);
- ok = FALSE;
- }
- if (MyPoint = MyAllocMem(sizeof(struct MyPoint),MEMF_CLEAR)) {
- MyPoint->x = xx;
- MyPoint->y = yy;
- MyPoint->x1 = x1;
- MyPoint->y1 = y1;
- AddTail(&PointList,(struct Node *)MyPoint);
- ++PointCount;
- }
- else {
- ok = FALSE;
- }
- }
- }
- Depth = MyArgInt("DEPTH",2,FALSE);
- Depth = min(Depth,20);
- Mode = MyArgInt("MODE",0,FALSE);
- if ((Single == 2) || (Single == 3)) {
- Mode &= ~MODE_ONCE; // Irrelevant for anims
- }
- if (ok) {
- // if ((PointsAlloc = MyAllocVec((max(PointCount,23) + 3)*sizeof(struct MyPoint *) *
- if ((PointsAlloc = MyAllocVec((Depth + 4)*sizeof(struct MyPoint *) * // + 1 = NumPoints
- ((Mode & MODE_ONCE)?width*height:1),MEMF_CLEAR)) &&
- (PointsX = MyAllocVec((max(PointCount,23) + 3)*sizeof(struct MyPoint *),MEMF_CLEAR)) &&
- (PointsY = MyAllocVec((max(PointCount,23) + 3)*sizeof(struct MyPoint *),MEMF_CLEAR))) {
- // Set up x and y order
- Points = PointsAlloc;
- i = 0;
- for (MyPoint = (struct MyPoint *)PointList.lh_Head;
- MyPoint->MyNode.mln_Succ;
- MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ) {
- PointsX[i] = MyPoint;
- PointsY[i] = MyPoint;
- ++i;
- }
- }
- else {
- Error("Out of memory for points","Quit",NULL,H_MemPointsR);
- ok = FALSE;
- }
- }
- // Close file and cleanup
- if (!Close(fh)) {
- if (ok) {
- Error("Error closing file '%s'","Quit",filename,H_CloseFile);
- ok = FALSE;
- }
- }
- }
- else {
- Error("Error opening file '%s'","Quit",filename,H_Open);
- ok = FALSE;
- }
- }
- else {
- ok = FALSE;
- }
- return ok;
- }
-
- /* Delete all the points from the list */
- void
- DeleteAllPoints(void) {
- struct MyPoint *MyPoint;
- // Loops looking at the head every time and deletes it
- while ((MyPoint =(struct MyPoint *)PointList.lh_Head)->MyNode.mln_Succ) {
- Remove((struct Node *)MyPoint);
- MyFreeMem(MyPoint,sizeof(struct MyPoint));
- }
- if (PointsAlloc) {
- MyFreeVec(PointsAlloc);
- PointsAlloc = NULL;
- }
- if (PointsX) {
- MyFreeVec(PointsX);
- PointsX = NULL;
- }
- if (PointsY) {
- MyFreeVec(PointsY);
- PointsY = NULL;
- }
- }
-
- // The following is the alogrithm stuff!!!!!
- // and is not particularly well commented!
-
- /* Given a point, returns the coordinates in the first and last image */
- static void __regargs
- FindPoint(struct MyPoint *RetPoint,BOOL Everything) {
- UWORD KeepCount;
- struct MyPoint *MyPoint,*MyPoint1,*MyPoint2;
- struct MyPoint **p,**p1,**p2,**p3;
- UWORD i1,i2;
- UWORD i,j,k;
- LONG checkdiff;
- BOOL flag;
- UWORD NumPoints;
- UWORD add;
- struct Triangle *T;
- UWORD MinX,MaxX,CurX; // Pointers to X array
- UWORD MinY,MaxY,CurY; // Pointers to Y array
- int l;
-
- if (!(Mode & MODE_ONCE) || !Everything) {
- if (Mode & MODE_SEARCH) {
- p = PointsX;
- for (i = 0;
- i < PointCount;
- ++i) {
- (*p)->Used = FALSE;
- ++p;
- }
- flag = FALSE;
- CurX = PointCount>>1;
- add = CurX>>1;
- if (!add) {
- add = 1;
- }
- p = &(PointsX[CurX]);
- p2 = &(PointsX[PointCount -1]);
- while (!flag) {
- if ((*p)->Cx == x) {
- flag = TRUE;
- MinX = CurX-1;
- MaxX = CurX+1;
- }
- else {
- if ((*p)->Cx < x) {
- ++p;
- if ((*p)->Cx > x) {
- flag = TRUE;
- MinX = CurX;
- MaxX = CurX+1;
- }
- else {
- CurX += add;
- p += (add-1);
- if (p == p2) {
- flag = TRUE;
- MinX = CurX-1;
- MaxX = CurX;
- }
- }
- }
- else {
- CurX -= add;
- if (!CurX) {
- flag = TRUE;
- MinX = 0;
- MaxX = 1;
- }
- else {
- p -= add;
- }
- }
- }
- if (!flag) {
- add >>= 1;
- if (!add) {
- add = 1;
- }
- }
- }
- flag = FALSE;
- CurY = PointCount>>1;
- add = CurY>>1;
- if (!add) {
- add = 1;
- }
- p = &(PointsY[CurY]);
- p2 = &(PointsY[PointCount -1]);
- while (!flag) {
- if ((*p)->Cy == y) {
- flag = TRUE;
- MinY = CurY-1;
- MaxY = CurY+1;
- }
- else {
- if ((*p)->Cy < y) {
- ++p;
- if ((*p)->Cy > y) {
- flag = TRUE;
- MinY = CurY;
- MaxY = CurY+1;
- }
- else {
- CurY += add;
- p += (add-1);
- if (p == p2) {
- flag = TRUE;
- MinY = CurY-1;
- MaxY = CurY;
- }
- }
- }
- else {
- CurY -= add;
- if (!CurY) {
- flag = TRUE;
- MinY = 0;
- MaxY = 1;
- }
- else {
- p -= add;
- }
- }
- }
- if (!flag) {
- add >>= 1;
- if (!add) {
- add = 1;
- }
- }
- }
- NumPoints = 0; // Count of points found so far
- while ((NumPoints < (Depth+3)) && (NumPoints < PointCount)) {
- p = &(PointsX[MinX]);
- for (i = MinX;
- (i <= MaxX) && (NumPoints < (Depth+3));
- ++i,++p) {
- if (!(*p)->Used) {
- flag = TRUE;
- MyPoint = *p;
- p1 = &(PointsY[MinY]);
- for (j = MinY;
- (j <= MaxY) && flag;
- ++j,++p1) {
- if (MyPoint == *p1) {
- if (x < MyPoint->Cx) {
- MyPoint->xdiff = MyPoint->Cx - x;
- }
- else {
- MyPoint->xdiff = x - MyPoint->Cx;
- }
- if (y < MyPoint->Cy) {
- MyPoint->ydiff = MyPoint->Cy - y;
- }
- else {
- MyPoint->ydiff = y - MyPoint->Cy;
- }
- MyPoint->Cdiff = MyPoint->xdiff * MyPoint->xdiff +
- MyPoint->ydiff * MyPoint->ydiff;
- flag = TRUE;
- p2 = Points;
- for (k = 0;
- flag && (k < NumPoints);
- ++k,++p2) {
- if ((*p2)->Cdiff > MyPoint->Cdiff) {
- MyPoint1 = *p2;
- *p2 = MyPoint;
- p3 = p2;
- ++p3;
- for (l = k+1;
- l < NumPoints;
- ++l,++p3) {
- MyPoint2 = *p3;
- *p3 = MyPoint1;
- MyPoint1 = MyPoint2;
- }
- flag = FALSE;
- }
- }
- if (flag) {
- *p2 = MyPoint;
- }
- MyPoint->Used = TRUE;
- NumPoints++;
- flag = FALSE;
- }
- }
- }
- }
- if (MinX > 0) {
- --MinX;
- }
- if (MinY > 0) {
- --MinY;
- }
- if (MaxX < (PointCount -1)) {
- ++MaxX;
- }
- if (MaxY < (PointCount -1)) {
- ++MaxY;
- }
- }
- }
- else {
- NumPoints = Depth+3;
- p = Points;
- for (i = 0;
- i < NumPoints;
- ++i) {
- *(p++) = &BigPoint;
- }
- // Set up differences
- p2 = &(Points[Depth+2]);
- for (MyPoint = (struct MyPoint *)PointList.lh_Head;
- MyPoint->MyNode.mln_Succ;
- MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ) {
- if (x < MyPoint->Cx) {
- MyPoint->xdiff = MyPoint->Cx - x;
- }
- else {
- MyPoint->xdiff = x - MyPoint->Cx;
- }
- if (y < MyPoint->Cy) {
- MyPoint->ydiff = MyPoint->Cy - y;
- }
- else {
- MyPoint->ydiff = y - MyPoint->Cy;
- }
- if ((MyPoint->xdiff + MyPoint->ydiff) < (*p2)->Cdiff) {
- MyPoint->Cdiff = MyPoint->xdiff * MyPoint->xdiff +
- MyPoint->ydiff * MyPoint->ydiff;
- flag = TRUE;
- p = Points;
- for (i = 0;
- flag && (i < NumPoints);
- ++i,++p) {
- if ((*p)->Cdiff > MyPoint->Cdiff) {
- MyPoint1 = *p;
- *p = MyPoint;
- p1 = p;
- ++p1;
- for (j = i+1;
- j < (Depth + 3);
- ++j,++p1) {
- MyPoint2 = *p1;
- *p1 = MyPoint1;
- MyPoint1 = MyPoint2;
- }
- flag = FALSE;
- }
- }
- }
- }
- }
- if (!Everything) {
- Points[Depth+3] = (struct MyPoint *)NumPoints;
- return;
- }
- }
- else {
- p = Points;
- NumPoints = (ULONG)Points[Depth+3];
- for (i = 0;
- ((i < Depth+3) && *p);
- ++i,++p) {
- MyPoint = *p;
- if (x < MyPoint->Cx) {
- MyPoint->xdiff = MyPoint->Cx - x;
- }
- else {
- MyPoint->xdiff = x - MyPoint->Cx;
- }
- if (y < MyPoint->Cy) {
- MyPoint->ydiff = MyPoint->Cy - y;
- }
- else {
- MyPoint->ydiff = y - MyPoint->Cy;
- }
- MyPoint->Cdiff = MyPoint->xdiff * MyPoint->xdiff +
- MyPoint->ydiff * MyPoint->ydiff;
- }
- }
- // If on an actual point then easy
- if (!Points[0]->Cdiff) {
- if (AntiAlias) {
- RetPoint->xd = Points[0]->x;
- RetPoint->x1d = Points[0]->x1;
- RetPoint->yd = Points[0]->y;
- RetPoint->y1d = Points[0]->y1;
- }
- else {
- RetPoint->x = Points[0]->x;
- RetPoint->x1 = Points[0]->x1;
- RetPoint->y = Points[0]->y;
- RetPoint->y1 = Points[0]->y1;
- }
- return;
- }
- // otherwise try and find a triangle with the other points
- if (!Depth && !(Mode & (MODE_STAT | MODE_DELAU))) {
- // Special case, only have 3 points
- MyPoint = Points[0];
- MyPoint1 = Points[1];
- MyPoint2 = Points[2];
- }
- else {
- KeepCount = 0;
- if (Mode & MODE_DELAU) {
- MyPoint = Points[0];
- for (T = (struct Triangle *)MyPoint->TList.lh_Head;
- T->TNode.mln_Succ && !KeepCount;
- T = (struct Triangle *)T->TNode.mln_Succ) {
- i1 = intersect(MyPoint,T->Point1);
- if (i1 + (i2 = intersect(T->Point1,T->Point2)) < 2) {
- if ((i1 + i2 + intersect(T->Point2,MyPoint)) == 1) {
- MyPoint1 = T->Point1;
- MyPoint2 = T->Point2;
- KeepCount = 1;
- }
- }
- }
- }
- else {
- if (Mode & MODE_CLOSEST) {
- checkdiff = 0x7FFFFFFF;
- for (p = Points, i=0;
- i<(NumPoints-2);
- ++i,++p) {
- if ((*p)->Cdiff < checkdiff) {
- for (p1 = p+1, j=i;
- j<(NumPoints-2);
- ++j,++p1) {
- if (((*p)->Cdiff + (*p1)->Cdiff) < checkdiff) {
- i1 = intersect(*p,*p1);
- for (p2 = p1+1, k=j;
- k<(NumPoints-2);
- ++k,++p2) {
- // loop thru 3 point combinations finding smallest triangle
- if (((*p)->Cdiff + (*p1)->Cdiff + (*p2)->Cdiff) < checkdiff) {
- if (i1 + (i2 = intersect(*p1,*p2)) < 2) {
- if ((i1 + i2 + intersect(*p2,*p)) == 1) {
- KeepCount = 1;
- MyPoint = *p;
- MyPoint1 = *p1;
- MyPoint2 = *p2;
- checkdiff = (*p)->Cdiff + (*p1)->Cdiff + (*p2)->Cdiff;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- else {
- for (p = Points, i=0;
- !KeepCount && (i<(NumPoints-2));
- ++i,++p) {
- for (p1 = p+1, j=i;
- !KeepCount && (j<(NumPoints-2));
- ++j,++p1) {
- i1 = intersect(*p,*p1);
- for (p2 = p1+1, k=j;
- !KeepCount && (k<(NumPoints-2));
- ++k,++p2) {
- // loop thru 3 point combinations finding smallest triangle
- if (i1 + (i2 = intersect(*p1,*p2)) < 2) {
- if ((i1 + i2 + intersect(*p2,*p)) == 1) {
- MyPoint = *p;
- MyPoint1 = *p1;
- MyPoint2 = *p2;
- KeepCount = 1;
- }
- }
- }
- }
- }
- }
- }
- // If still no triangle then assume stationary
- if (!KeepCount && (Mode & MODE_STAT)) {
- if (AntiAlias) {
- RetPoint->xd = x;
- RetPoint->x1d = x;
- RetPoint->yd = y;
- RetPoint->y1d = y;
- }
- else {
- RetPoint->x = x;
- RetPoint->y = y;
- RetPoint->x1 = x;
- RetPoint->y1 = y;
- }
- return;
- }
- if (!KeepCount) {
- MyPoint = Points[0];
- MyPoint1 = Points[1];
- MyPoint2 = Points[2];
- }
- }
- // Otherwise do the triangle calculation
- if (Integer) {
- Triangle_I(RetPoint,MyPoint,MyPoint1,MyPoint2);
- }
- else {
- Triangle(RetPoint,MyPoint,MyPoint1,MyPoint2);
- }
- // Check the point is actually on the image
- if (AntiAlias) {
- if (RetPoint->xd < 0) {
- RetPoint->xd = 0;
- }
- if (RetPoint->yd < 0) {
- RetPoint->yd = 0;
- }
- if (RetPoint->x1d < 0) {
- RetPoint->x1d = 0;
- }
- if (RetPoint->y1d < 0) {
- RetPoint->y1d = 0;
- }
- if (RetPoint->xd > (width-1)) {
- RetPoint->xd = width-1;
- }
- if (RetPoint->yd > (height-1)) {
- RetPoint->yd = height-1;
- }
- if (RetPoint->x1d > (width-1)) {
- RetPoint->x1d = width-1;
- }
- if (RetPoint->y1d > (height-1)) {
- RetPoint->y1d = height-1;
- }
- }
- else {
- if (RetPoint->x < 0) {
- RetPoint->x = 0;
- }
- if (RetPoint->y < 0) {
- RetPoint->y = 0;
- }
- if (RetPoint->x1 < 0) {
- RetPoint->x1 = 0;
- }
- if (RetPoint->y1 < 0) {
- RetPoint->y1 = 0;
- }
- if (RetPoint->x > (width-1)) {
- RetPoint->x = width-1;
- }
- if (RetPoint->y > (height-1)) {
- RetPoint->y = height-1;
- }
- if (RetPoint->x1 > (width-1)) {
- RetPoint->x1 = width-1;
- }
- if (RetPoint->y1 > (height-1)) {
- RetPoint->y1 = height-1;
- }
- }
- }
-
- /* Used to determine if a point lies on a line,
- * or in triangle of 3 points
- */
- static UWORD __regargs
- #ifdef __SASC_60
- __inline
- #endif
- intersect(struct MyPoint *Pointa,struct MyPoint *Pointb) {
- // Draws line between a and b and sees if line from x,0 to x,y intersects
- // returns 1 if intersects, 0 if not intersect
- if (Pointb->Cx == Pointa->Cx) { // Vertical a to b
- if ((Pointb->x == x) && // x,y on a to b
- (((Pointb->Cy > y) && (Pointa->Cy < y)) ||
- ((Pointb->Cy < y) && (Pointa->Cy > y)))) {
- return 1; // Beteen a and b
- }
- return 0;
- }
- if (((Pointb->Cy > y) && (Pointa->Cy > y)) ||
- ((Pointb->Cx > x) && (Pointa->Cx > x)) ||
- ((Pointb->Cx < x) && (Pointa->Cx < x))) { // Can not possibly cross
- return 0;
- }
- if ((Pointb->Cy < y) && (Pointa->Cy < y)) {
- return 1;
- }
- if (Pointa->Cx == x) {
- if (Pointa->Cy > y) {
- return 0;
- }
- return 1;
- }
- if (Pointb->Cx == x) {
- if (Pointb->Cy > y) {
- return 0;
- }
- return 1;
- }
- if (Pointb->Cy == Pointa->Cy) {
- if (Pointa->Cy > y) {
- return 0;
- }
- return 1;
- }
- if ((((Pointa->Cx < x)?(x - Pointa->Cx):(Pointa->Cx - x)) * Pointb->Cy +
- ((Pointb->Cx < x)?(x - Pointb->Cx):(Pointb->Cx - x)) * Pointa->Cy) /
- ((Pointb->Cx < Pointa->Cx)?(Pointa->Cx - Pointb->Cx):(Pointb->Cx - Pointa->Cx)) > y) {
- return 0;
- }
- return 1;
- }
-
- /* Given 3 points (a,b,c) with a point (p) in the triangle
- * determine the coordinates of point (p) on the first and last frame
- */
- static void __regargs
- #ifdef __SASC_60
- __inline
- #endif
- Triangle(struct MyPoint *p,struct MyPoint *a,struct MyPoint *bb,struct MyPoint *c) {
- double AB1,AB2,BC1,BC2,CA1,CA2;
- double AB,BC,CA;
- double ABBCCA2;
- double ABCA,BCCA,ABBC;
- double BC1BC2,AB1AB2,CA1CA2;
- CalcDiffs(a,bb,&AB1,&AB2,&AB);
- CalcDiffs(bb,c,&BC1,&BC2,&BC);
- CalcDiffs(c,a,&CA1,&CA2,&CA);
- ABBCCA2 = 2 * (AB + BC + CA);
- ABCA = AB+CA;
- BCCA = BC+CA;
- ABBC = AB+BC;
- BC1BC2 = BC1+BC2;
- AB1AB2 = AB1+AB2;
- CA1CA2 = CA1+CA2;
- if (AntiAlias) {
- p->xd = x +
- (ABCA*(BC1*(c->x - c->Cx) + BC2*(bb->x - bb->Cx)) / BC1BC2 +
- BCCA*(AB1*(bb->x - bb->Cx) + AB2*(a->x - a->Cx)) / AB1AB2 +
- ABBC*(CA1*(a->x - a->Cx) + CA2*(c->x - c->Cx)) / CA1CA2) /
- ABBCCA2;
- p->x1d = x +
- (ABCA*(BC1*(c->x1 - c->Cx) + BC2*(bb->x1 - bb->Cx)) / BC1BC2 +
- BCCA*(AB1*(bb->x1 - bb->Cx) + AB2*(a->x1 - a->Cx)) / AB1AB2 +
- ABBC*(CA1*(a->x1 - a->Cx) + CA2*(c->x1 - c->Cx)) / CA1CA2) /
- ABBCCA2;
- p->y1d = y +
- (ABCA*(BC1*(c->y1 - c->Cy) + BC2*(bb->y1 - bb->Cy)) / BC1BC2 +
- BCCA*(AB1*(bb->y1 - bb->Cy) + AB2*(a->y1 - a->Cy)) / AB1AB2 +
- ABBC*(CA1*(a->y1 - a->Cy) + CA2*(c->y1 - c->Cy)) / CA1CA2) /
- ABBCCA2;
- p->yd = y +
- (ABCA*(BC1*(c->y - c->Cy) + BC2*(bb->y - bb->Cy)) / BC1BC2 +
- BCCA*(AB1*(bb->y - bb->Cy) + AB2*(a->y - a->Cy)) / AB1AB2 +
- ABBC*(CA1*(a->y - a->Cy) + CA2*(c->y - c->Cy)) / CA1CA2) /
- ABBCCA2;
- }
- else {
- p->x = x +
- (ABCA*(BC1*(c->x - c->Cx) + BC2*(bb->x - bb->Cx)) / BC1BC2 +
- BCCA*(AB1*(bb->x - bb->Cx) + AB2*(a->x - a->Cx)) / AB1AB2 +
- ABBC*(CA1*(a->x - a->Cx) + CA2*(c->x - c->Cx)) / CA1CA2) /
- ABBCCA2;
- p->x1 = x +
- (ABCA*(BC1*(c->x1 - c->Cx) + BC2*(bb->x1 - bb->Cx)) / BC1BC2 +
- BCCA*(AB1*(bb->x1 - bb->Cx) + AB2*(a->x1 - a->Cx)) / AB1AB2 +
- ABBC*(CA1*(a->x1 - a->Cx) + CA2*(c->x1 - c->Cx)) / CA1CA2) /
- ABBCCA2;
- p->y1 = y +
- (ABCA*(BC1*(c->y1 - c->Cy) + BC2*(bb->y1 - bb->Cy)) / BC1BC2 +
- BCCA*(AB1*(bb->y1 - bb->Cy) + AB2*(a->y1 - a->Cy)) / AB1AB2 +
- ABBC*(CA1*(a->y1 - a->Cy) + CA2*(c->y1 - c->Cy)) / CA1CA2) /
- ABBCCA2;
- p->y = y +
- (ABCA*(BC1*(c->y - c->Cy) + BC2*(bb->y - bb->Cy)) / BC1BC2 +
- BCCA*(AB1*(bb->y - bb->Cy) + AB2*(a->y - a->Cy)) / AB1AB2 +
- ABBC*(CA1*(a->y - a->Cy) + CA2*(c->y - c->Cy)) / CA1CA2) /
- ABBCCA2;
- }
- }
-
- /* Caclulate the distances between various points */
- static void __regargs
- #ifdef __SASC_60
- __inline
- #endif
- CalcDiffs(struct MyPoint *a,struct MyPoint *bb,double *ab1,double *ab2,double *ab) {
- // ab is length x,y to line ab
- // ab1 is length x,y to intersect of ab
- // ab2 is length intersect of ab to bb
- double m;
- double c; // y = mx+c line a to bb
- double n;
- double d; // y = nx+d line perp to y=mx+c thru x,y
- double xsolve,ysolve;
- if (a->Cx == bb->Cx) {
- *ab = a->xdiff;
- *ab1 = a->ydiff;
- *ab2 = bb->ydiff;
- }
- else {
- if (a->Cy == bb->Cy) {
- *ab1 = a->xdiff;
- *ab2 = bb->xdiff;
- *ab = a->ydiff;
- }
- else {
- m = (double)(bb->Cy - a->Cy) / (double)(bb->Cx - a->Cx);
- c = bb->Cy - (bb->Cx * m);
- n = (-1) / m;
- d = y - n * x;
- xsolve = (d - c)/(m - n);
- ysolve = m * xsolve + c;
- *ab1 = sqrt(((a->Cy - ysolve) * (a->Cy - ysolve) + (a->Cx - xsolve) * (a->Cx - xsolve)));
- *ab2 = sqrt(((bb->Cy - ysolve) * (bb->Cy - ysolve) + (bb->Cx - xsolve) * (bb->Cx - xsolve)));
- *ab = sqrt(((y - ysolve) * (y - ysolve) + (x - xsolve) * (x - xsolve)));
- }
- }
- }
-
- /* Given 3 points (a,b,c) with a point (p) in the triangle
- * determine the coordinates of point (p) on the first and last frame
- * Integer version
- * Completely different to the real version
- */
- static void __regargs
- #ifdef __SASC_60
- __inline
- #endif
- Triangle_I(struct MyPoint *p,struct MyPoint *a,struct MyPoint *bb,struct MyPoint *c) {
- LONG ABBCCA2;
- ABBCCA2 = 2 * (a->Cdiff + bb->Cdiff + c->Cdiff);
- p->x = x +
- ((a->x - a->Cx) * (bb->Cdiff + c->Cdiff) +
- (bb->x - bb->Cx) * (a->Cdiff + c->Cdiff) +
- (c->x - c->Cx) * (a->Cdiff + bb->Cdiff)) /
- ABBCCA2;
- p->x1 = x +
- ((a->x1 - a->Cx) * (bb->Cdiff + c->Cdiff) +
- (bb->x1 - bb->Cx) * (a->Cdiff + c->Cdiff) +
- (c->x1 - c->Cx) * (a->Cdiff + bb->Cdiff)) /
- ABBCCA2;
- p->y = y +
- ((a->y - a->Cy) * (bb->Cdiff + c->Cdiff) +
- (bb->y - bb->Cy) * (a->Cdiff + c->Cdiff) +
- (c->y - c->Cy) * (a->Cdiff + bb->Cdiff)) /
- ABBCCA2;
- p->y1 = y +
- ((a->y1 - a->Cy) * (bb->Cdiff + c->Cdiff) +
- (bb->y1 - bb->Cy) * (a->Cdiff + c->Cdiff) +
- (c->y1 - c->Cy) * (a->Cdiff + bb->Cdiff)) /
- ABBCCA2;
- }
-
- // Load some image(s) for a frame
- BOOL
- LoadFrames(BOOL points,BOOL image1,BOOL image2) {
- char buffer[257];
- BOOL ok=TRUE;
- UBYTE *er,*eg,*eb;
- int i;
- if ((Single == 2) || (Single == 3)) {
- if (points) {
- AddMessage("Loading points");
- DeleteAllPoints();
- sprintf(buffer,MyFileName,f+Start-1);
- ok = MyOpen(buffer,TRUE);
- }
- sprintf(buffer,Pic1.filename,f+Start-1);
- }
- else {
- strcpy(buffer,Pic1.filename);
- }
- if (ok) {
- if (image1) {
- ok = Pic1_Open = Load24bit(buffer,&Pic1,TRUE);
- if (ok && EGS && !EGS_BitMap) {
- if (EGS_BitMap = E_AllocBitMap(swidth,1,24,E_PIXELMAP,E_EB_NOTSWAPABLE,NULL)) {
- EGS_NewWindow.LeftEdge = 0;
- EGS_NewWindow.TopEdge = 20;
- EGS_NewWindow.Width = width;
- EGS_NewWindow.Height = height;
- EGS_NewWindow.MinWidth = 20;
- EGS_NewWindow.MinHeight = 20;
- EGS_NewWindow.MaxWidth = width;
- EGS_NewWindow.MaxHeight = height;
- EGS_NewWindow.Screen = NULL;
- EGS_NewWindow.Bordef.SysGadgets = EI_WINDOWSIZE | EI_WINDOWFRONT | EI_WINDOWFLIP |
- EI_WINDOWARROWL | EI_WINDOWARROWR | EI_WINDOWARROWU | EI_WINDOWARROWD |
- EI_WINDOWSCROLLH | EI_WINDOWSCROLLV | EI_WINDOWDRAG;
- EGS_NewWindow.FirstGadgets = NULL;
- EGS_NewWindow.Title = "TSMorph-render output";
- EGS_NewWindow.Flags = EI_GIMMEZEROZERO | EI_SUPER_BITMAP | EI_WINDOWACTIVE | EI_REPORTMOUSE | EI_QUICKSCROLL | EI_RMBTRAP;
- EGS_NewWindow.IDCMPFlags = NULL;
- EGS_NewWindow.Port = NULL;
- // EGS_NewWindow.Colors = ??;
- EGS_NewWindow.Menu = NULL;
- EGS_NewWindow.Render = NULL;
- if (EGS_Win = EI_OpenWindow(&EGS_NewWindow)) {
- EI_SetWindowTitles(EGS_Win,(UBYTE *)-1,"TSMorph-render");
- E_ActivateEGSScreen();
- er = Pic1.red;
- eg = Pic1.green;
- eb = Pic1.blue;
- for (i = 0; i<height; ++i) {
- CopyEGS(i,&er,&eg,&eb);
- }
- }
- }
- }
- }
- if (image2 && ok && ((Single == 0) || (Single == 2))) {
- // If we loaded the 1st image then try the second
- if (Single == 2) {
- sprintf(buffer,Pic2.filename,f+Start-1);
- }
- else {
- strcpy(buffer,Pic2.filename);
- }
- ok = Pic2_Open = Load24bit(buffer,&Pic2,TRUE);
- }
- }
- return ok;
- }
-
- void
- CopyEGS(int line, UBYTE **er,UBYTE **eg,UBYTE **eb) {
- int j;
- UBYTE *plane;
- plane = ((struct E_EBitMapFull *)EGS_BitMap)->Typekey.PixelMap.Planes.Dest;
- for (j = 0; j<swidth; ++j) {
- *plane++ = *((*er)++);
- *plane++ = *((*eg)++);
- *plane++ = *((*eb)++);
- ++plane;
- }
- EG_CopyBitMapRastPort(EGS_BitMap,EGS_Win->RPort,0,0,width,1,0,line);
- }
-
- int
- cmpX(struct MyPoint **A,struct MyPoint **B) {
- if ((*A)->Cx < (*B)->Cx) {
- return -1;
- }
- if ((*A)->Cx > (*B)->Cx) {
- return 1;
- }
- return 0;
- }
-
- int
- cmpY(struct MyPoint **A,struct MyPoint **B) {
- if ((*A)->Cy < (*B)->Cy) {
- return -1;
- }
- if ((*A)->Cy > (*B)->Cy) {
- return 1;
- }
- return 0;
- }
-
- int
- cmpDiff(struct MyPoint **A,struct MyPoint **B) {
- if ((*A)->Cdiff < (*B)->Cdiff) {
- return -1;
- }
- if ((*A)->Cdiff > (*B)->Cdiff) {
- return 1;
- }
- return 0;
- }
-
- /* nsort() was written by Dave Watson and uses the algorithm described in -
- * Watson, D.F., 1981, Computing the n-dimensional Delaunay tessellation with
- * application to Voronoi polytopes: The Computer J., 24(2), p. 167-172.
- */
-
- #define SQ(x) (x) * (x)
- #define BIGNUM 1E37
- #define EPSILON 0.00001
- #define TSIZE 75 /* temporary storage size factor*/
- #define XRANGE 10.0 /* factor (>=1) for radius of control points */
- #define FILENAMELEN 32
- #define AND &&
- #define OR ||
- #define EQ ==
- #define NE !=
-
- BOOL
- GenerateTriangles(void) {
- BOOL ok = FALSE;
- BOOL flag = TRUE;
- double xx, bgs, **mxy, **wrk, **pts, **ccr;
- int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i11, ii[3],
- dm, nts, tsz, *id, **tmp, **a3s;
-
- if (mxy = DoubleMatrix(2, 2)) {
- for (i0=0; i0<2; i0++) {
- mxy[0][i0] = - (mxy[1][i0] = BIGNUM);
- }
- if (wrk = DoubleMatrix(2, 3)) {
- for (i0=0; i0<2; i0++) {
- for (i1=0; i1<3; i1++) {
- wrk[i0][i1] = -XRANGE;
- }
- }
- for (i0=0; i0<2; i0++) {
- wrk[i0][i0] = XRANGE * (3 * 2 - 1);
- }
- if (pts = DoubleMatrix(PointCount + 3, 2)) {
- for (i0=0; i0<PointCount; i0++) {
- NewList(&(PointsX[i0]->TList));
- pts[i0][0] = PointsX[i0]->Cx;
- pts[i0][1] = PointsX[i0]->Cy;
- for (i1=0; i1<2; i1++) {
- if (mxy[0][i1] < pts[i0][i1]) {
- mxy[0][i1] = pts[i0][i1];
- }
- if (mxy[1][i1] > pts[i0][i1]) {
- mxy[1][i1] = pts[i0][i1];
- }
- }
- }
- for (bgs=0, i0=0; i0<2; i0++) {
- mxy[0][i0] -= mxy[1][i0];
- if (bgs < mxy[0][i0]) {
- bgs = mxy[0][i0];
- }
- }
- bgs *= EPSILON;
- for (i0=0; i0<PointCount; i0++) {
- for (i1=0; i1<2; i1++) {
- pts[i0][i1] += bgs * (0.5 - (double)rand() / 0x7fffffff);
- }
- }
- for (i0=0; i0<3; i0++) {
- for (i1=0; i1<2; i1++) {
- pts[PointCount+i0][i1] = mxy[1][i1] + wrk[i1][i0] * mxy[0][i1];
- }
- }
- for (i1=1, i0=2; i0<3; i0++) {
- i1 *= i0;
- }
- tsz = TSIZE * i1;
- if (tmp = IntMatrix(tsz + 1, 2)) {
- i1 *= (PointCount + i1);
- if (id = IntVect(i1)) {
- for (i0=0; i0<i1; i0++) {
- id[i0] = i0;
- }
- if (a3s = IntMatrix(i1,3)) {
- if (ccr = DoubleMatrix(i1,3)) {
- for (a3s[0][0]=PointCount, i0=1; i0<3; i0++) {
- a3s[0][i0] = a3s[0][i0-1] + 1;
- }
- for (ccr[0][2]=BIGNUM, i0=0; i0<2; i0++) {
- ccr[0][i0] = 0;
- }
- nts = i4 = 1;
- dm = 2 - 1;
- for (i0=0; i0<PointCount; i0++) {
- i1 = i7 = -1;
- i9 = 0;
- for (i11=0; i11<nts; i11++) {
- i1++;
- while (a3s[i1][0] < 0) {
- i1++;
- }
- xx = ccr[i1][2];
- for (i2=0; i2<2; i2++) {
- xx -= SQ(pts[i0][i2] - ccr[i1][i2]);
- if (xx<0) {
- goto Corner3;
- }
- }
- i9--;
- i4--;
- id[i4] = i1;
- for (i2=0; i2<3; i2++) {
- ii[0] = 0;
- if (ii[0] EQ i2) {
- ii[0]++;
- }
- for (i3=1; i3<2; i3++) {
- ii[i3] = ii[i3-1] + 1;
- if (ii[i3] EQ i2) {
- ii[i3]++;
- }
- }
- if (i7>dm) {
- i8 = i7;
- for (i3=0; i3<=i8; i3++) {
- for (i5=0; i5<2; i5++) {
- if (a3s[i1][ii[i5]] NE tmp[i3][i5]) {
- goto Corner1;
- }
- }
- for (i6=0; i6<2; i6++) {
- tmp[i3][i6] = tmp[i8][i6];
- }
- i7--;
- goto Corner2;
- Corner1:;
- }
- }
- if (++i7 > tsz) {
- goto returnfail;
- }
- for (i3=0; i3<2; i3++) {
- tmp[i7][i3] = a3s[i1][ii[i3]];
- }
- Corner2:;
- }
- a3s[i1][0] = -1;
- Corner3:;
- }
- for (i1=0; i1<=i7; i1++) {
- for (i2=0; i2<2; i2++) {
- for (wrk[i2][2]=0, i3=0; i3<2; i3++) {
- wrk[i2][i3] = pts[tmp[i1][i2]][i3] - pts[i0][i3];
- wrk[i2][2] += wrk[i2][i3] * (pts[tmp[i1][i2]][i3] + pts[i0][i3]) / 2;
- }
- }
- xx = wrk[0][0] * wrk[1][1] - wrk[1][0] * wrk[0][1];
- ccr[id[i4]][0] = (wrk[0][2] * wrk[1][1] - wrk[1][2] * wrk[0][1]) / xx;
- ccr[id[i4]][1] = (wrk[0][0] * wrk[1][2] - wrk[1][0] * wrk[0][2]) / xx;
- for (ccr[id[i4]][2]=0, i2=0; i2<2; i2++) {
- ccr[id[i4]][2] += SQ(pts[i0][i2] - ccr[id[i4]][i2]);
- a3s[id[i4]][i2] = tmp[i1][i2];
- }
- a3s[id[i4]][2] = i0;
- i4++;
- i9++;
- }
- nts += i9;
- }
- i0 = -1;
- for (i11=0; flag && (i11<nts); i11++) {
- i0++;
- while (a3s[i0][0] < 0) {
- i0++;
- }
- if (a3s[i0][0] < PointCount) {
- for (i1=0; i1<2; i1++) for (i2=0; i2<2; i2++) {
- wrk[i1][i2] = pts[a3s[i0][i1]][i2] - pts[a3s[i0][2]][i2];
- }
- xx = wrk[0][0] * wrk[1][1] - wrk[0][1] * wrk[1][0];
- if (fabs(xx) > EPSILON) {
- flag = AddTri(a3s[i0][0],a3s[i0][2],a3s[i0][1]);
- }
- }
- }
- ok = flag;
- returnfail:
- FreeMatrixd(ccr);
- }
- FreeMatrixi(a3s);
- }
- MyFreeVecti(id);
- }
- FreeMatrixi(tmp);
- }
- FreeMatrixd(pts);
- }
- FreeMatrixd(wrk);
- }
- FreeMatrixd(mxy);
- }
- return ok;
- }
-
- int
- *IntVect(int ncols) {
- return (int *) MyAllocVec(ncols * sizeof(int),0);
- }
-
- void
- MyFreeVecti(int *vectptr) {
- if (vectptr) {
- MyFreeVec(vectptr);
- }
- }
-
- int
- **IntMatrix(int nrows, int ncols) {
- int i0;
- int **matptr;
- if (nrows<2) nrows = 2;
- if (ncols<2) ncols = 2;
- if ((matptr = (int **) MyAllocVec(nrows * sizeof(int *),0)) EQ NULL) {
- return NULL;
- }
- if ((matptr[0] = (int *) MyAllocVec(nrows * ncols * sizeof(int),0)) EQ NULL) {
- MyFreeVec(matptr);
- return NULL;
- }
- for (i0=1; i0<nrows; i0++) {
- matptr[i0] = matptr[0] + i0 * ncols;
- }
- return matptr;
- }
-
- void
- FreeMatrixi(int **matptr) {
- if (matptr) {
- if (matptr[0]) {
- MyFreeVec(matptr[0]);
- }
- MyFreeVec(matptr);
- }
- }
-
- double
- **DoubleMatrix(int nrows, int ncols) {
- int i0;
- double **matptr;
- if (nrows<2) nrows = 2;
- if (ncols<2) ncols = 2;
- if ((matptr = (double **) MyAllocVec(nrows * sizeof(double *),0)) EQ NULL) {
- return NULL;
- }
- if ((matptr[0] = (double *) MyAllocVec(nrows * ncols * sizeof(double),0)) EQ NULL) {
- MyFreeVec(matptr);
- return NULL;
- }
- for (i0=1; i0<nrows; i0++) {
- matptr[i0] = matptr[0] + i0 * ncols;
- }
- return matptr;
- }
-
- void
- FreeMatrixd(double **matptr) {
- if (matptr) {
- if (matptr[0]) {
- MyFreeVec(matptr[0]);
- }
- MyFreeVec(matptr);
- }
- }
-
- void
- FreeTriangles(void) {
- int i;
- struct Triangle *T;
- struct MyPoint *P;
- for (i=0; i<PointCount; i++) {
- P = PointsX[i];
- while ((T =(struct Triangle *)(P->TList.lh_Head))->TNode.mln_Succ) {
- Remove((struct Node *)T);
- MyFreeVec(T);
- }
- }
- }
-
- BOOL AddTri(int aa,int bb,int cc) {
- struct Triangle *T1,*T2=NULL,*T3;
- if ((T1 = (struct Triangle *)MyAllocVec(sizeof (struct Triangle),0)) &&
- (T2 = (struct Triangle *)MyAllocVec(sizeof (struct Triangle),0)) &&
- (T3 = (struct Triangle *)MyAllocVec(sizeof (struct Triangle),0))) {
- T1->Point1 = PointsX[bb];
- T1->Point2 = PointsX[cc];
- AddTail(&(PointsX[aa]->TList),(struct Node *)T1);
- T2->Point1 = PointsX[aa];
- T2->Point2 = PointsX[cc];
- AddTail(&(PointsX[bb]->TList),(struct Node *)T2);
- T3->Point1 = PointsX[aa];
- T3->Point2 = PointsX[bb];
- AddTail(&(PointsX[cc]->TList),(struct Node *)T3);
- return TRUE;
- }
- if (T1) {
- MyFreeVec(T1);
- }
- if (T2) {
- MyFreeVec(T2);
- }
- return FALSE;
- }
-
- static UWORD top = 0;
-
- // add a message to the progress list
- void
- AddMessage(UBYTE *message) {
- struct Node *node;
- if ((node = (struct Node *)Mymalloc(sizeof(struct Node))) &&
- (node->ln_Name = Mystrdup(message))) {;
- GT_SetGadgetAttrs(ProgressGadgets[GDX_Info],ProgressWnd,NULL,
- GTLV_Labels, ~0,
- TAG_END);
- AddTail(&InfoList,node);
- GT_SetGadgetAttrs(ProgressGadgets[GDX_Info],ProgressWnd,NULL,
- GTLV_Labels, &InfoList,
- GTLV_Top, top,
- TAG_END);
- top++;
- }
- }
-